Example #1
0
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]);
    }
  }
}
Example #2
0
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]);
  }
}
Example #3
0
/*
 *  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;
}