static void gamma5_flip(wilson_vector *milc, int parity){ int i,c; site *s; FORSOMEPARITY(i,s,parity){ for(c = 0; c < 3; c++){ CNEGATE(milc[i].d[2].c[c],milc[i].d[2].c[c]); CNEGATE(milc[i].d[3].c[c],milc[i].d[3].c[c]); } } }
void random_gauge_trans(Twist_Fermion *TF) { int a, b, i, j, x = 1, t = 1, s = node_index(x, t); complex tc; matrix Gmat, tmat, etamat, psimat[NUMLINK], chimat; if (this_node != 0) { printf("random_gauge_trans: only implemented in serial so far\n"); fflush(stdout); terminate(1); } if (nx < 4 || nt < 4) { printf("random_gauge_trans: doesn't deal with boundaries, "); printf("needs to be run on larger volume\n"); fflush(stdout); terminate(1); } // Set up random gaussian matrix, then unitarize it clear_mat(&tmat); for (j = 0; j < DIMF; j++) { #ifdef SITERAND tc.real = gaussian_rand_no(&(lattice[0].site_prn)); tc.imag = gaussian_rand_no(&(lattice[0].site_prn)); #else tc.real = gaussian_rand_no(&(lattice[0].node_prn)); tc.imag = gaussian_rand_no(&(lattice[0].node_prn)); #endif c_scalar_mult_sum_mat(&(Lambda[j]), &tc, &tmat); } polar(&tmat, &Gmat); // Confirm unitarity or check invariance when Gmat = I // mult_na(&Gmat, &Gmat, &tmat); // dumpmat(&tmat); // mat_copy(&tmat, &Gmat); // Left side of local eta clear_mat(&etamat); // Construct G eta = sum_j eta^j G Lambda^j for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Fsite.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &etamat); } // Project out eta^j = -Tr[Lambda^j G eta] for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &etamat, &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fsite.c[j]); } // Right side of local eta clear_mat(&etamat); // Construct eta Gdag = sum_j eta^j Lambda^j Gdag for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Fsite.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &etamat); } // Project out eta^j = -Tr[eta Gdag Lambda^j] for (j = 0; j < DIMF; j++) { mult_nn(&etamat, &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fsite.c[j]); } // Left side of local links and psis; right side of local chis FORALLDIR(a) { mult_nn(&Gmat, &(lattice[s].link[a]), &tmat); mat_copy(&tmat, &(lattice[s].link[a])); clear_mat(&(psimat[a])); for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Flink[a].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[a])); } for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &(psimat[a]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[a].c[j]); } for (b = a + 1; b < NUMLINK; b++) { clear_mat(&(chimat)); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Fplaq.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(chimat)); } for (j = 0; j < DIMF; j++) { mult_nn(&(chimat), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fplaq[i].c[j]); } } } // Right side of neighboring links and psis // TODO: Presumably we can convert this to a loop... s = node_index(x - 1, t); mult_na(&(lattice[s].link[0]), &Gmat, &tmat); mat_copy(&tmat, &(lattice[s].link[0])); clear_mat(&(psimat[0])); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Flink[0].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[0])); } for (j = 0; j < DIMF; j++) { mult_nn(&(psimat[0]), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[0].c[j]); } s = node_index(x, t - 1); mult_na(&(lattice[s].link[3]), &Gmat, &tmat); mat_copy(&tmat, &(lattice[s].link[3])); clear_mat(&(psimat[3])); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Flink[3].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[3])); } for (j = 0; j < DIMF; j++) { mult_nn(&(psimat[3]), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[3].c[j]); } // Left side of neighboring chi s = node_index(x - 1, t - 1); i = plaq_index[0][3]; clear_mat(&(chimat[i])); for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Fplaq[i].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(chimat[i])); } for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &(chimat[i]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fplaq[i].c[j]); } }
/* * Computes meson 2pt function for gammas: * g5-g5, g5-g4g5, g4g5-g5, g4g5-g4g5, g1-g1, g2-g2, g3-g3 * * The function does not return anything. It writes the correlation functions * to a file (as ascii). * * Updated for non-zero momentum correlator. Correlator calculated explicitely * for all momentum vectors (i.e. non-FFT) * */ void qpb_mesons_2pt_corr(qpb_spinor_field *light, qpb_spinor_field *heavy, int max_q2, char outfile[]) { if(heavy == NULL) heavy = light; /* This should never happen. For now the package is built so that only x, y and z are parallelized accross MPI and t along OpenMP */ if(problem_params.par_dir[0] == 1) { error(" %s() not implemented for distributed t-direction, quiting\n", __func__); exit(QPB_NOT_IMPLEMENTED_ERROR); } int lvol = problem_params.l_vol; int lt = problem_params.l_dim[0]; int lvol3d = lvol/lt; qpb_complex **corr_x; qpb_complex **corr_k; qpb_complex **corr[QPB_N_MESON_2PT_CHANNELS]; int N = (NS*NS*NS*NS); qpb_complex prod[N]; int ndirac = 0; int mu[N],nu[N],ku[N],lu[N]; qpb_complex gamma_5x[NS][NS]; qpb_complex gamma_5y[NS][NS]; qpb_complex gamma_5z[NS][NS]; int nmom = 0, nq = (int)sqrt(max_q2)+1; int (*mom)[4]; /* Count momentum vectors <= max_q2 */ for(int z=-nq; z<nq; z++) for(int y=-nq; y<nq; y++) for(int x=-nq; x<nq; x++) { double q2 = x*x+y*y+z*z; if(q2 <= max_q2) nmom++; } mom = qpb_alloc(sizeof(int)*4*nmom); nmom = 0; /* Store momentum vectors <= max_q2 */ for(int z=-nq; z<nq; z++) for(int y=-nq; y<nq; y++) for(int x=-nq; x<nq; x++) { double q2 = x*x+y*y+z*z; if(q2 <= max_q2) { mom[nmom][3] = x; mom[nmom][2] = y; mom[nmom][1] = z; mom[nmom][0] = q2; nmom++; } } /* Sort in ascending q^2 value */ for(int i=0; i<nmom; i++) { int x = mom[i][0]; /* the q^2 value */ int k = i; for(int j=i+1; j<nmom; j++) if(mom[j][0] < x) { k = j; x = mom[j][0]; } int swap[] = {mom[k][0], mom[k][1], mom[k][2], mom[k][3]}; for(int j=0; j<4; j++) mom[k][j] = mom[i][j]; for(int j=0; j<4; j++) mom[i][j] = swap[j]; } corr_x = qpb_alloc(lt * sizeof(qpb_complex *)); corr_k = qpb_alloc(lt * sizeof(qpb_complex *)); for(int t=0; t<lt; t++) { corr_x[t] = qpb_alloc(lvol3d * sizeof(qpb_complex)); corr_k[t] = qpb_alloc(nmom * sizeof(qpb_complex)); } for(int ich=0; ich<QPB_N_MESON_2PT_CHANNELS; ich++) { corr[ich] = qpb_alloc(nmom * sizeof(qpb_complex *)); for(int p=0; p<nmom; p++) corr[ich][p] = qpb_alloc(lt * sizeof(qpb_complex)); ndirac = 0; switch(ich) { case S_S: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(CMUL(qpb_gamma_5[i][j],qpb_gamma_5[k][l])) > 0.5 ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = CMUL(qpb_gamma_5[i][j],qpb_gamma_5[k][l]); ndirac++; } } break; case G5_G5: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(i==j && k==l) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = (qpb_complex){1.,0.}; ndirac++; } } break; case G5_G4G5: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(i==j && CNORM(qpb_gamma_t[k][l]) > 0.5) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = qpb_gamma_t[k][l]; ndirac++; } } break; case G4G5_G5: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(qpb_gamma_t[i][j]) > 0.5 && k==l ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = qpb_gamma_t[i][j]; ndirac++; } } break; case G4G5_G4G5: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(CMUL(qpb_gamma_t[i][j],qpb_gamma_t[k][l])) > 0.5 ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = CMUL(qpb_gamma_t[i][j],qpb_gamma_t[k][l]); ndirac++; } } break; case G1_G1: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) { gamma_5x[i][j] = (qpb_complex){0., 0.}; for(int k=0; k<NS; k++) { gamma_5x[i][j].re += CMULR(qpb_gamma_5[i][k], qpb_gamma_x[k][j]); gamma_5x[i][j].im += CMULI(qpb_gamma_5[i][k], qpb_gamma_x[k][j]); } } for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(CMUL(gamma_5x[i][j],gamma_5x[k][l])) > 0.5 ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = CNEGATE(CMUL(gamma_5x[i][j],gamma_5x[k][l])); ndirac++; } } break; case G2_G2: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) { gamma_5y[i][j] = (qpb_complex){0., 0.}; for(int k=0; k<NS; k++) { gamma_5y[i][j].re += CMULR(qpb_gamma_5[i][k], qpb_gamma_y[k][j]); gamma_5y[i][j].im += CMULI(qpb_gamma_5[i][k], qpb_gamma_y[k][j]); } } for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(CMUL(gamma_5y[i][j],gamma_5y[k][l])) > 0.5 ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = CNEGATE(CMUL(gamma_5y[i][j],gamma_5y[k][l])); ndirac++; } } break; case G3_G3: for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) { gamma_5z[i][j] = (qpb_complex){0., 0.}; for(int k=0; k<NS; k++) { gamma_5z[i][j].re += CMULR(qpb_gamma_5[i][k], qpb_gamma_z[k][j]); gamma_5z[i][j].im += CMULI(qpb_gamma_5[i][k], qpb_gamma_z[k][j]); } } for(int i=0; i<NS; i++) for(int j=0; j<NS; j++) for(int k=0; k<NS; k++) for(int l=0; l<NS; l++) { if(CNORM(CMUL(gamma_5z[i][j],gamma_5z[k][l])) > 0.5 ) { mu[ndirac] = i; nu[ndirac] = j; ku[ndirac] = k; lu[ndirac] = l; prod[ndirac] = CNEGATE(CMUL(gamma_5z[i][j],gamma_5z[k][l])); ndirac++; } } break; } for(int t=0; t<lt; t++) for(int lv=0; lv<lvol3d; lv++) corr_x[t][lv] = (qpb_complex){0., 0.}; for(int col0=0; col0<NC; col0++) for(int col1=0; col1<NC; col1++) for(int id=0; id<ndirac; id++) { int i = mu[id]; int j = nu[id]; int k = ku[id]; int l = lu[id]; #ifdef OPENMP # pragma omp parallel for #endif for(int t=0; t<lt; t++) for(int lv=0; lv<lvol3d; lv++) { int v = blk_to_ext[lv + t*lvol3d]; qpb_complex hp = ((qpb_complex *)(light[col0+NC*l].index[v]))[col1+NC*i]; qpb_complex lp = ((qpb_complex *)(heavy[col0+NC*k].index[v]))[col1+NC*j]; /* c = x * conj(y) */ qpb_complex c = {hp.re*lp.re + hp.im*lp.im, hp.im*lp.re - hp.re*lp.im}; corr_x[t][lv].re += CMULR(prod[id], c); corr_x[t][lv].im += CMULI(prod[id], c); } } qpb_ft(corr_k, corr_x, lt, mom, nmom); for(int t=0; t<lt; t++) for(int p=0; p<nmom; p++) corr[ich][p][t] = corr_k[t][p]; } FILE *fp = NULL; if(am_master) { if((fp = fopen(outfile, "w")) == NULL) { error("%s: error opening file in \"w\" mode\n", outfile); MPI_Abort(MPI_COMM_WORLD, QPB_FILE_ERROR); exit(QPB_FILE_ERROR); } } for(int t=0; t<lt; t++) { char ctag[QPB_MAX_STRING]; for(int p=0; p<nmom; p++) for(int ich=0; ich<QPB_N_MESON_2PT_CHANNELS; ich++) { switch(ich) { case S_S: strcpy(ctag ,"1-1"); break; case G5_G5: strcpy(ctag ,"g5-g5"); break; case G5_G4G5: strcpy(ctag ,"g5-g4g5"); break; case G4G5_G5: strcpy(ctag ,"g4g5-g5"); break; case G4G5_G4G5: strcpy(ctag ,"g4g5-g4g5"); break; case G1_G1: strcpy(ctag ,"g1-g1"); break; case G2_G2: strcpy(ctag ,"g2-g2"); break; case G3_G3: strcpy(ctag ,"g3-g3"); break; } if(am_master) fprintf(fp, " %+2d %+2d %+2d %3d %+e %+e %s\n", mom[p][3], mom[p][2], mom[p][1], t, corr[ich][p][t].re, corr[ich][p][t].im, ctag); } } if(am_master) fclose(fp); for(int t=0; t<lt; t++) { free(corr_x[t]); free(corr_k[t]); } free(corr_x); free(corr_k); for(int ich=0; ich<QPB_N_MESON_2PT_CHANNELS; ich++) { for(int p=0; p<nmom; p++) free(corr[ich][p]); free(corr[ich]); } free(mom); return; }