Exemplo n.º 1
0
/* the "full" operators */
void Q_pm_psi_prec(spinor * const l, spinor * const k)
{
  spinorPrecWS *ws=(spinorPrecWS*)g_precWS;

  _Complex double ALIGN alpha= -1.0;

  if(g_prec_sequence_d_dagger_d[0]!=0.0)
  {
    alpha = g_prec_sequence_d_dagger_d[0];
    spinorPrecondition(l,k,ws,T,L,alpha,0,1);
  } 
  else
    assign(l,k,VOLUME);

  g_mu = -g_mu;
  D_psi(g_spinor_field[DUM_MATRIX], l);
  gamma5(l, g_spinor_field[DUM_MATRIX], VOLUME);
  g_mu = -g_mu;

  if(g_prec_sequence_d_dagger_d[1]!=0.0)
  {
    alpha = g_prec_sequence_d_dagger_d[1];
    spinorPrecondition(l,l,ws,T,L,alpha,0,1);
  }

  D_psi(g_spinor_field[DUM_MATRIX], l);
  gamma5(l, g_spinor_field[DUM_MATRIX], VOLUME);

  if(g_prec_sequence_d_dagger_d[2]!=0.0)
  {
    alpha = g_prec_sequence_d_dagger_d[2]; 
    spinorPrecondition(l,l,ws,T,L,alpha,0,1);
  }

}
Exemplo n.º 2
0
void Qov_sq_psi(spinor * const P, spinor * const S) {
  Dov_psi(g_spinor_field[DUM_MATRIX], S);
  gamma5(g_spinor_field[DUM_MATRIX], g_spinor_field[DUM_MATRIX], VOLUME);
  Dov_psi(P,g_spinor_field[DUM_MATRIX]);
  gamma5(P,P, VOLUME);

  return;
}
Exemplo n.º 3
0
/* This is the version for the gpu (Florian Burger)*/
void Q_minus_psi_gpu(spinor * const l, spinor * const k)
{
  gamma5(k,k,VOLUME);
  g_mu = -g_mu;
  D_psi(l, k);
  g_mu = -g_mu;
  gamma5(l, l, VOLUME);
}
Exemplo n.º 4
0
/* the "full" operators */
void Q_pm_psi2(spinor * const l, spinor * const k)
{
  g_mu = -10.*g_mu;
  D_psi(l, k);
  gamma5(g_spinor_field[DUM_MATRIX], l, VOLUME);
  g_mu = -g_mu/10.;
  D_psi(l, g_spinor_field[DUM_MATRIX]);
  gamma5(l, l, VOLUME);
}
Exemplo n.º 5
0
/* This is the version for the gpu with interchanged order of gamma5 and D_psi (Florian Burger)*/
void Q_pm_psi_gpu(spinor * const l, spinor * const k)
{
  gamma5(k, k, VOLUME);
  g_mu = -g_mu;
  D_psi(l, k);
  gamma5(g_spinor_field[DUM_MATRIX], l, VOLUME);
  g_mu = -g_mu;
  D_psi(l, g_spinor_field[DUM_MATRIX]);
  
}
Exemplo n.º 6
0
int invert_cloverdoublet_eo(spinor * const Even_new_s, spinor * const Odd_new_s, 
			    spinor * const Even_new_c, spinor * const Odd_new_c, 
			    spinor * const Even_s, spinor * const Odd_s,
			    spinor * const Even_c, spinor * const Odd_c,
			    const double precision, const int max_iter,
			    const int solver_flag, const int rel_prec) {
  
  int iter = 0;
  
  
  /* here comes the inversion using even/odd preconditioning */
  if(g_proc_id == 0) {printf("# Using even/odd preconditioning!\n"); fflush(stdout);}
  Msw_ee_inv_ndpsi(Even_new_s, Even_new_c, 
		   Even_s, Even_c);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even_new_s);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI+1], Even_new_c);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_mul_add_r(g_spinor_field[DUM_DERI], +1., Odd_s, VOLUME/2);
  assign_mul_add_r(g_spinor_field[DUM_DERI+1], +1., Odd_c, VOLUME/2);
  
  /* Do the inversion with the preconditioned  */
  /* matrix to get the odd sites               */
  
  /* Here we invert the hermitean operator squared */
  
  if(g_proc_id == 0) {
    printf("# Using CG for TMWILSON flavour doublet!\n"); 
    fflush(stdout);
  }
  gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
  gamma5(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], VOLUME/2);
  
  iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
		   max_iter, precision, rel_prec, 
		   VOLUME/2, &Qsw_pm_ndpsi);
  
  
  Qsw_dagger_ndpsi(Odd_new_s, Odd_new_c,
		   Odd_new_s, Odd_new_c);
  
  /* Reconstruct the even sites                */
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd_new_s);
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI+1], Odd_new_c);
  Msw_ee_inv_ndpsi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3],
		   g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_add_mul_r(Even_new_s, g_spinor_field[DUM_DERI+2], +1., VOLUME/2);
  assign_add_mul_r(Even_new_c, g_spinor_field[DUM_DERI+3], +1., VOLUME/2);
  
  return(iter);
}
Exemplo n.º 7
0
void Q_full(spinor * const Even_new, spinor * const Odd_new, 
	    spinor * const Even, spinor * const Odd) {
  /* Even sites */
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd);
  assign_mul_one_pm_imu(Even_new, Even, 1., VOLUME/2); 
  assign_add_mul_r(Even_new, g_spinor_field[DUM_DERI], -1., VOLUME/2);
  gamma5(Even_new, Even_new, VOLUME/2);

  /* Odd sites */
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even);
  assign_mul_one_pm_imu(Odd_new, Odd, 1., VOLUME/2); 
  assign_add_mul_r(Odd_new, g_spinor_field[DUM_DERI], -1., VOLUME/2);
  gamma5(Odd_new, Odd_new, VOLUME/2);
}
Exemplo n.º 8
0
void Qtm_pm_sym_psi(spinor * const l, spinor * const k){
  /* Q_{-} */
  Hopping_Matrix(EO, g_spinor_field[DUM_MATRIX+1], k);
  mul_one_pm_imu_inv(g_spinor_field[DUM_MATRIX+1], -1., VOLUME/2);
  Hopping_Matrix(OE, g_spinor_field[DUM_MATRIX], g_spinor_field[DUM_MATRIX+1]);
  mul_one_pm_imu_inv(g_spinor_field[DUM_MATRIX], -1., VOLUME/2);
  diff(l, k, g_spinor_field[DUM_MATRIX], VOLUME/2);
  gamma5(l, l, VOLUME/2);

  /* Q_{+} */
  Hopping_Matrix(EO, l, g_spinor_field[DUM_MATRIX]);
  mul_one_pm_imu_inv(l, +1., VOLUME/2);
  Hopping_Matrix(OE, g_spinor_field[DUM_MATRIX+1], l);
  mul_one_pm_imu_inv(g_spinor_field[DUM_MATRIX], +1., VOLUME/2);
  diff(l, k, g_spinor_field[DUM_MATRIX], VOLUME/2);
  gamma5(l, l, VOLUME/2);

}
Exemplo n.º 9
0
/* |R>=rnorm^2 Q^2 |S> */
void norm_Q_sqr_psi(spinor * const R, spinor * const S, 
		    const double rnorm) { 

  spinor *aux;
  aux=lock_Dov_WS_spinor(1);

  /* Term -1-s is done in D_psi! does this comment make sense for HMC? */
  /* no, it doesn't, we do have to work on this */
  /* here we need to set kappa = 1./(2 (-1-s) + 8) */
  D_psi(R, S);
  gamma5(aux, R, VOLUME);
  D_psi(R, aux);
  gamma5(R, R, VOLUME);
  mul_r(R, rnorm*rnorm, R, VOLUME);

  unlock_Dov_WS_spinor(1);
  return;
}
Exemplo n.º 10
0
void Qov_sq_psi_prec(spinor * const P, spinor * const S) {


  spinorPrecWS *ws=(spinorPrecWS*)g_precWS;
  static complex alpha={0,0};

  alpha.re=ws->precExpo[0];
  spinorPrecondition(P,S,ws,T,L,alpha,0,1);


  Dov_psi(g_spinor_field[DUM_MATRIX], P);
  gamma5(P, g_spinor_field[DUM_MATRIX], VOLUME);

  alpha.re=ws->precExpo[1];
  spinorPrecondition(P,P,ws,T,L,alpha,0,1);

  Dov_psi(g_spinor_field[DUM_MATRIX], P);
  gamma5(P, g_spinor_field[DUM_MATRIX], VOLUME);

  alpha.re=ws->precExpo[2];
  spinorPrecondition(P,P,ws,T,L,alpha,0,1);

  return;
}
Exemplo n.º 11
0
void addproj_q_invsqrt(spinor * const Q, spinor * const P, const int n, const int N) {
  
  int j;
  spinor  *aux;
  complex cnorm, lambda;
  static double save_ev[2]={-1.,-1.};
  static int * ev_sign = NULL;
  
  if(eigenvls[0] != save_ev[0] && eigenvls[1] != save_ev[1] ) {
    if(g_proc_id == 0 && g_debug_level > 1) {
      printf("# Recomputing eigenvalue signs!\n");
      fflush(stdout);
    }
    for(j = 0; j < 2; j++) {
      save_ev[j] = eigenvls[j];
    }
    free(ev_sign);
    ev_sign = (int*) malloc(n * sizeof(int));

    aux=lock_Dov_WS_spinor(1);

    for(j=0; j < n; j++) {
      D_psi(aux, &(eigenvectors[j*evlength]));
      gamma5(aux, aux, N);
      
      lambda = scalar_prod(&(eigenvectors[j*evlength]), aux, N, 1);
      if (lambda.re < 0) {
	ev_sign[j] = -1;
      }
      else {
	ev_sign[j] = 1;
      }
    }

    unlock_Dov_WS_spinor(1);
/*     free(aux_); */
  }

  for(j = 0; j < n; j++) {
    cnorm = scalar_prod(&(eigenvectors[j*evlength]), P, N, 1);
    
    cnorm.re *= (double)ev_sign[j];
    cnorm.im *= (double)ev_sign[j];
    
    assign_add_mul(Q, &(eigenvectors[j*evlength]), cnorm, N);
  }
  return;
}
Exemplo n.º 12
0
void CGeoSmoother(spinor * const P, spinor * const Q, const int Ncy, const int dummy) {
  spinor ** solver_field = NULL;
  const int nr_sf = 5;
  double musave = g_mu;
  g_mu = g_mu1;
  init_solver_field(&solver_field, VOLUMEPLUSRAND/2, nr_sf);
  
  convert_lexic_to_eo(solver_field[0], solver_field[1], Q);
  if(g_c_sw > 0)
    assign_mul_one_sw_pm_imu_inv(EE,solver_field[2], solver_field[0], g_mu);
  else
    assign_mul_one_pm_imu_inv(solver_field[2], solver_field[0], +1., VOLUME/2);
  
  Hopping_Matrix(OE, solver_field[4], solver_field[2]); 
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_mul_add_r(solver_field[4], +1., solver_field[1], VOLUME/2);
  /* Do the inversion with the preconditioned  */
  /* matrix to get the odd sites               */
  gamma5(solver_field[4], solver_field[4], VOLUME/2);
  if(g_c_sw > 0) {
    cg_her(solver_field[3], solver_field[4], Ncy, 1.e-8, 1, 
	   VOLUME/2, &Qsw_pm_psi);
    Qsw_minus_psi(solver_field[3], solver_field[3]);
    
    /* Reconstruct the even sites                */
    Hopping_Matrix(EO, solver_field[2], solver_field[3]);
    assign_mul_one_sw_pm_imu_inv(EE,solver_field[4],solver_field[2], g_mu);
  }
  else {
    cg_her(solver_field[3], solver_field[4], Ncy, 1.e-8, 1, 
	   VOLUME/2, &Qtm_pm_psi);
    Qtm_minus_psi(solver_field[3], solver_field[3]);
    
    /* Reconstruct the even sites                */
    Hopping_Matrix(EO, solver_field[4], solver_field[3]);
    mul_one_pm_imu_inv(solver_field[4], +1., VOLUME/2);
  }
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_add_mul_r(solver_field[2], solver_field[4], +1., VOLUME/2);
  
  convert_eo_to_lexic(P, solver_field[2], solver_field[3]); 
  g_mu = musave;
  finalize_solver(solver_field, nr_sf);
  return;  
}
Exemplo n.º 13
0
void Dov_psi(spinor * const P, spinor * const S) {

  double c0,c1;
  spinor *s;
  static int n_cheby = 0;
  static int rec_coefs = 1;

  ov_s = 0.5*(1./g_kappa - 8.) - 1.;
/*   printf("Degree of Polynomial set to %d\n", ov_n_cheby); */
  if(n_cheby != ov_n_cheby || rec_coefs) {
    calculateOverlapPolynomial();
    n_cheby = ov_n_cheby;
    rec_coefs = 0;
  }

  if(dov_ws==NULL){
    init_Dov_WS();
  }

/*   s_ = calloc(VOLUMEPLUSRAND+1, sizeof(spinor)); */

/* #if (defined SSE3 || defined SSE2 || defined SSE) */
/*   s = (spinor*)(((unsigned long int)(s_)+ALIGN_BASE)&~ALIGN_BASE); */
/* #else */
/*   s = s_; */
/* #endif */

  s=lock_Dov_WS_spinor(0);

  /* here we do with M = 1 + s */
  /* M + m_ov/2 + (M - m_ov/2) \gamma_5 sign(Q(-M)) */
  c0 = -(1.0 + ov_s - 0.5*m_ov);
  c1 = -(1.0 + ov_s + 0.5*m_ov);

  Q_over_sqrt_Q_sqr(s, ov_cheby_coef, ov_n_cheby, S, ev_qnorm, ev_minev);
  gamma5(s, s, VOLUME);
  assign_mul_add_mul_r(s, S, c0, c1, VOLUME);
  assign(P, s, VOLUME);

/*   free(s_); */
  unlock_Dov_WS_spinor(0);
  return;
}
Exemplo n.º 14
0
int bicg(spinor * const k, spinor * const l, double eps_sq) {
  int iteration;
  double xxx;
  xxx=0.0;
  gamma5(g_spinor_field[DUM_SOLVER+1], l, VOLUME/2);
  /* main loop */
  for(iteration=1;iteration<=ITER_MAX_BCG;iteration++) {
    /* compute the residual*/
    M_psi(DUM_SOLVER,k,q_off);
    xxx=diff_and_square_norm(g_spinor_field[DUM_SOLVER], g_spinor_field[DUM_SOLVER+1], VOLUME/2);
    /*apply the solver step for the residual*/
    M_psi(DUM_SOLVER+2,DUM_SOLVER,q_off-(2.+2.*q_off));
    assign_add_mul_r(k,-1./((1.+q_off)*(1.+q_off)),g_spinor_field[DUM_SOLVER+2], VOLUME/2);
    if(xxx <= eps_sq) break;
  }

  if(g_proc_id==0) {
    sout = fopen(solvout, "a");
    fprintf(sout, "%d %e %f\n",iteration,xxx, g_mu);
    fclose(sout);
  }

  /* if the geometric series fails, redo with conjugate gradient */
  if(iteration>=ITER_MAX_BCG) {
    if(ITER_MAX_BCG == 0) {
      iteration = 0;
    }
    zero_spinor_field(k,VOLUME/2);
    iteration += solve_cg(k,l,q_off,eps_sq);
    Q_psi(k,k,q_off);
    if(ITER_MAX_BCG != 0) {
      iteration -= 1000000;
    }
    if(g_proc_id == 0) {
      sout = fopen(solvout, "a");
      fprintf(sout, "%d %e\n",iteration, g_mu);
      fclose(sout);
    }
  }
  
  return iteration;
}
Exemplo n.º 15
0
/* |R>=rnorm^n Q^n |S>                                                     */
void norm_Q_n_psi(spinor * const R, spinor * const S, 
		  const int n, const double rnorm) { 

  int i;
  double npar = 1.;
  spinor *aux;

  aux=lock_Dov_WS_spinor(1);

  assign(aux, S, VOLUME);
  
  
  for(i=0; i < n; i++){
    D_psi(R, aux);
    /* Term -1-s is done in D_psi! does this comment make sense for HMC? */
    gamma5(aux, R, VOLUME);
    npar *= rnorm;
  }
  mul_r(R, npar, aux, VOLUME);
  unlock_Dov_WS_spinor(1);
  return;
}
Exemplo n.º 16
0
void cloverdet_derivative(const int id, hamiltonian_field_t * const hf) {
  monomial * mnl = &monomial_list[id];

  /* This factor 2 a missing factor 2 in trace_lambda */
  (*mnl).forcefactor = 2.;

  
  /*********************************************************************
   * 
   * even/odd version 
   *
   * This a term is det(\hat Q^2(\mu))
   *
   *********************************************************************/
  
  g_mu = mnl->mu;
  g_mu3 = mnl->rho;
  boundary(mnl->kappa);
  
  // we compute the clover term (1 + T_ee(oo)) for all sites x
  sw_term(hf->gaugefield, mnl->kappa, mnl->c_sw); 
  // we invert it for the even sites only
  sw_invert(EE, mnl->mu);
  
  if(mnl->solver != CG && g_proc_id == 0) {
    fprintf(stderr, "Bicgstab currently not implemented, using CG instead! (cloverdet_monomial.c)\n");
  }
  
  // Invert Q_{+} Q_{-}
  // X_o -> DUM_DERI+1
  chrono_guess(g_spinor_field[DUM_DERI+1], mnl->pf, mnl->csg_field, mnl->csg_index_array,
	       mnl->csg_N, mnl->csg_n, VOLUME/2, mnl->Qsq);
  mnl->iter1 += cg_her(g_spinor_field[DUM_DERI+1], mnl->pf, mnl->maxiter, mnl->forceprec, 
		       g_relative_precision_flag, VOLUME/2, mnl->Qsq);
  chrono_add_solution(g_spinor_field[DUM_DERI+1], mnl->csg_field, mnl->csg_index_array,
		      mnl->csg_N, &mnl->csg_n, VOLUME/2);
  
  // Y_o -> DUM_DERI
  mnl->Qm(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);
  
  // apply Hopping Matrix M_{eo}
  // to get the even sites of X_e
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+1], EE, -mnl->mu);
  // \delta Q sandwitched by Y_o^\dagger and X_e
  deriv_Sb(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], hf); 
  
  // to get the even sites of Y_e
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI], EE, mnl->mu);
  // \delta Q sandwitched by Y_e^\dagger and X_o
  // uses the gauge field in hf and changes the derivative fields in hf
  deriv_Sb(EO, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], hf);
  
  // here comes the clover term...
  // computes the insertion matrices for S_eff
  // result is written to swp and swm
  // even/even sites sandwiched by gamma_5 Y_e and gamma_5 X_e
  gamma5(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+2], VOLUME/2);
  sw_spinor(EO, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3]);
  
  // odd/odd sites sandwiched by gamma_5 Y_o and gamma_5 X_o
  gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
  sw_spinor(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);
  
  // compute the contribution for the det-part
  // we again compute only the insertion matrices for S_det
  // the result is added to swp and swm
  // even sites only!
  sw_deriv(EE, mnl->mu);
  
  // now we compute
  // finally, using the insertion matrices stored in swm and swp
  // we compute the terms F^{det} and F^{sw} at once
  // uses the gaugefields in hf and changes the derivative field in hf
  sw_all(hf, mnl->kappa, mnl->c_sw);

  g_mu = g_mu1;
  g_mu3 = 0.;
  boundary(g_kappa);

  return;
}
Exemplo n.º 17
0
/* k output , l input */
int bicg(spinor * const k, spinor * const l, double eps_sq, const int rel_prec) {

  double err, d1, squarenorm=0.;
  complex rho0, rho1, omega, alpha, beta, nom, denom;
  int iteration, N=VOLUME/2;
  spinor * r, * p, * v, *hatr, * s, * t, * P, * Q;
  

  if(ITER_MAX_BCG > 0) {



    hatr = g_spinor_field[DUM_SOLVER];
    r = g_spinor_field[DUM_SOLVER+1];
    v = g_spinor_field[DUM_SOLVER+2];
    p = g_spinor_field[DUM_SOLVER+3];
    s = g_spinor_field[DUM_SOLVER+4];
    t = g_spinor_field[DUM_SOLVER+5];
    P = k;
    Q = l;

    squarenorm = square_norm(Q, VOLUME/2, 1);
    
    Mtm_plus_psi(r, P);
    gamma5(g_spinor_field[DUM_SOLVER], l, VOLUME/2);
    diff(p, hatr, r, N);
    assign(r, p, N);
    assign(hatr, p, N);
    rho0 = scalar_prod(hatr, r, N, 1);
    
    for(iteration = 0; iteration < ITER_MAX_BCG; iteration++){
      err = square_norm(r, N, 1);
      if(g_proc_id == g_stdio_proc && g_debug_level > 1) {
	printf("BiCGstab: iterations: %d res^2 %e\n", iteration, err);
	fflush(stdout);
      }
      if (((err <= eps_sq) && (rel_prec == 0)) 
	  || ((err <= eps_sq*squarenorm) && (rel_prec == 1))){
	break;
      }
      Mtm_plus_psi(v, p);
      denom = scalar_prod(hatr, v, N, 1);
      _div_complex(alpha, rho0, denom);
      assign(s, r, N);
      assign_diff_mul(s, v, alpha, N);
      Mtm_plus_psi(t, s);
      omega = scalar_prod(t,s, N, 1);
      d1 = square_norm(t, N, 1);
      omega.re/=d1; omega.im/=d1;
      assign_add_mul_add_mul(P, p, s, alpha, omega, N);
      assign(r, s, N);
      assign_diff_mul(r, t, omega, N);
      rho1 = scalar_prod(hatr, r, N, 1);
      _mult_assign_complex(nom, alpha, rho1);
      _mult_assign_complex(denom, omega, rho0);
      _div_complex(beta, nom, denom);
      omega.re=-omega.re; omega.im=-omega.im;
      assign_mul_bra_add_mul_ket_add(p, v, r, omega, beta, N);
      rho0.re = rho1.re; rho0.im = rho1.im;
    }
    
    if(g_proc_id==0 && g_debug_level > 0) {
      printf("BiCGstab: iterations: %d eps_sq: %1.4e\n", iteration, eps_sq); 
    }
  }
  else{
    iteration = ITER_MAX_BCG;
    gamma5(k, l, VOLUME/2);
  }

  /* if bicg fails, redo with conjugate gradient */
  if(iteration>=ITER_MAX_BCG){
    iteration = solve_cg(k,l,eps_sq, rel_prec);
    /* Save the solution for reuse! not needed since Chronological inverter is there */
    /*     assign(g_spinor_field[DUM_DERI+6], k, VOLUME/2); */
    Qtm_minus_psi(k, k);;
  }
  return iteration;
}
Exemplo n.º 18
0
void Q_plus_psi(spinor * const l, spinor * const k)
{
  D_psi(l, k);
  gamma5(l, l, VOLUME);
}
Exemplo n.º 19
0
/* Checks GW relation only by applying Dov to delta(0,0) */
void ov_check_ginsparg_wilson_relation(void) {

  double norm_diff, norm_left, norm_right, norm, max_rel = 0.0, min_left = 1.0e100, min_right = 1.0e100, max_diff = 0.0, min_norm = 1.0e100;
  int x, y, z, t, i;
  spinor *S_left, *S_right, *S_diff;

  /* get memory for the spinor fields */
  S_left  = ov_alloc_spinor();
  S_right = ov_alloc_spinor();
  S_diff  = ov_alloc_spinor();

  /* Create delta source at origin */
  source_spinor_field(g_spinor_field[1], g_spinor_field[0], 0, 0);
  convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]);

  /* S_right = D gamma_5 D */
  Dov_psi(g_spinor_field[3], g_spinor_field[2]);
  gamma5(S_left, g_spinor_field[3], VOLUME);
  Dov_psi(S_right, S_left);

  /* S_left = {gamma_5, D} */
  gamma5(g_spinor_field[3], g_spinor_field[2], VOLUME);
  Dov_psi(g_spinor_field[4], g_spinor_field[3]);
  add(S_left, S_left, g_spinor_field[4], VOLUME);

  /* S_diff = S_left-S_right */
  diff(S_diff, S_left, S_right, VOLUME);

  /* scan the whole lattice */
  printf("// test of the Ginsparg-Wilson relation\n");
  for(x=0; x<LX; x++)
    for(y = 0; y < LY; y++)
      for(z = 0; z < LZ; z++)
	for(t = 0; t < T; t++) {
	  i = g_ipt[t][x][y][z];
 	  _spinor_norm_sq(norm_diff, S_diff[i]); 
 	  _spinor_norm_sq(norm_left, S_left[i]); 
 	  _spinor_norm_sq(norm_right, S_right[i]); 
	  norm_diff = sqrt(norm_diff);
	  norm_left = sqrt(norm_left);
	  norm_right = sqrt(norm_right);
	  norm = norm_left+norm_right;
	  if (norm < min_norm)
	    min_norm = norm;
	  if (norm > 0.0) {
	    norm = 2.*norm_diff/norm;
	    if (norm > max_rel)
	      max_rel = norm;
	  }
	  if (norm_left < min_left)
	    min_left = norm_left;
	  if (norm_right < min_right)
	    min_right = norm_right;
	  if (norm_diff > max_diff)
	    max_diff = norm_diff;
	}

  /* print results */
  printf(" - maximum absoulte deviation: %.4le\n", max_diff);
  printf(" - maximum relative deviation: %.4le\n", max_rel);
  printf(" - minimum mean norm: %4.le\n", min_norm);
  printf(" - minimum norm {gamma_5, D}: %.4le\n", min_left);
  printf(" - minimum norm D gamma_5 D: %.4le\n", min_right);

  /* free memory */
  ov_free_spinor(S_left);
  ov_free_spinor(S_right);
  ov_free_spinor(S_diff);
}
Exemplo n.º 20
0
void Qov_psi(spinor * const P, spinor * const S) {
  Dov_psi(P, S);
  gamma5(P, P, VOLUME);
  return;
}
Exemplo n.º 21
0
int invert_doublet_eo(spinor * const Even_new_s, spinor * const Odd_new_s, 
		      spinor * const Even_new_c, spinor * const Odd_new_c, 
		      spinor * const Even_s, spinor * const Odd_s,
		      spinor * const Even_c, spinor * const Odd_c,
		      const double precision, const int max_iter,
		      const int solver_flag, const int rel_prec) {

  int iter = 0;
  
  
#ifdef HAVE_GPU
#  ifdef TEMPORALGAUGE
  
  /* initialize temporal gauge here */
  int retval;
  double dret1, dret2;
  double plaquette1 = 0.0;
  double plaquette2 = 0.0;
  
  if (usegpu_flag) {
    
    /* need VOLUME here (not N=VOLUME/2)*/
    if ((retval = init_temporalgauge_trafo(VOLUME, g_gauge_field)) != 0 ) {				// initializes the transformation matrices
      if (g_proc_id == 0) printf("Error while gauge fixing to temporal gauge. Aborting...\n");   	//	g_tempgauge_field as a copy of g_gauge_field
      exit(200);
    }
    
    /* do trafo */
    plaquette1 = measure_plaquette(g_gauge_field);
    apply_gtrafo(g_gauge_field, g_trafo);								// transformation of the gauge field
    plaquette2 = measure_plaquette(g_gauge_field);
    if (g_proc_id == 0) printf("\tPlaquette before gauge fixing: %.16e\n", plaquette1/6./VOLUME);
    if (g_proc_id == 0) printf("\tPlaquette after gauge fixing:  %.16e\n", plaquette2/6./VOLUME);
    
    /* do trafo to odd_s part of source */
    dret1 = square_norm(Odd_s, VOLUME/2 , 1);
    apply_gtrafo_spinor_odd(Odd_s, g_trafo);								// odd spinor transformation, strange
    dret2 = square_norm(Odd_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    /* do trafo to odd_c part of source */
    dret1 = square_norm(Odd_c, VOLUME/2 , 1);
    apply_gtrafo_spinor_odd(Odd_c, g_trafo);								// odd spinor transformation, charm
    dret2 = square_norm(Odd_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);       
    
    /* do trafo to even_s part of source */
    dret1 = square_norm(Even_s, VOLUME/2 , 1);
    apply_gtrafo_spinor_even(Even_s, g_trafo);							// even spinor transformation, strange
    dret2 = square_norm(Even_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    /* do trafo to even_c part of source */
    dret1 = square_norm(Even_c, VOLUME/2 , 1);
    apply_gtrafo_spinor_even(Even_c, g_trafo);							// even spinor transformation, charm
    dret2 = square_norm(Even_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
#    ifdef MPI
    xchange_gauge(g_gauge_field);
#    endif
    
  } 
#  endif  
#endif /* HAVE_GPU*/


  /* here comes the inversion using even/odd preconditioning */
  if(g_proc_id == 0) {printf("# Using even/odd preconditioning!\n"); fflush(stdout);}
  M_ee_inv_ndpsi(Even_new_s, Even_new_c, 
		 Even_s, Even_c,
		 g_mubar, g_epsbar);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even_new_s);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI+1], Even_new_c);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_mul_add_r(g_spinor_field[DUM_DERI], +1., Odd_s, VOLUME/2);
  assign_mul_add_r(g_spinor_field[DUM_DERI+1], +1., Odd_c, VOLUME/2);
  
  /* Do the inversion with the preconditioned  */
  /* matrix to get the odd sites               */
  
  /* Here we invert the hermitean operator squared */
  
  if(g_proc_id == 0) {
    printf("# Using CG for TMWILSON flavour doublet!\n"); 
    fflush(stdout);
  }
  gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
  gamma5(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], VOLUME/2);
  
  
#ifdef HAVE_GPU
  if (usegpu_flag) {	// GPU, mixed precision solver
#  if defined(MPI) && defined(PARALLELT)
    iter = mixedsolve_eo_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
			    max_iter, precision, rel_prec);
#  elif !defined(MPI) && !defined(PARALLELT)
    iter = mixedsolve_eo_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
			    max_iter, precision, rel_prec);
#  else
    printf("MPI and/or PARALLELT are not appropriately set for the GPU implementation. Aborting...\n");
    exit(-1);
#  endif
  }
  else {		// CPU, conjugate gradient
    iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
		     max_iter, precision, rel_prec, 
		     VOLUME/2, &Qtm_pm_ndpsi);
  }
#else			// CPU, conjugate gradient
  iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
		   max_iter, precision, rel_prec, 
		   VOLUME/2, &Qtm_pm_ndpsi);
#endif
  
  
  Qtm_dagger_ndpsi(Odd_new_s, Odd_new_c,
		   Odd_new_s, Odd_new_c);

  /* Reconstruct the even sites                */
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd_new_s);
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI+1], Odd_new_c);
  M_ee_inv_ndpsi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3],
		 g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
		 g_mubar, g_epsbar);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_add_mul_r(Even_new_s, g_spinor_field[DUM_DERI+2], +1., VOLUME/2);
  assign_add_mul_r(Even_new_c, g_spinor_field[DUM_DERI+3], +1., VOLUME/2);
  
  
#ifdef HAVE_GPU  
  /* return from temporal gauge again */
#  ifdef TEMPORALGAUGE
  
  if (usegpu_flag) { 
    
    /* undo trafo */
    /* apply_inv_gtrafo(g_gauge_field, g_trafo);*/
    /* copy back the saved original field located in g_tempgauge_field -> update necessary*/
    plaquette1 = measure_plaquette(g_gauge_field);
    copy_gauge_field(g_gauge_field, g_tempgauge_field);
    g_update_gauge_copy = 1;
    plaquette2 = measure_plaquette(g_gauge_field);
    if (g_proc_id == 0) printf("\tPlaquette before inverse gauge fixing: %.16e\n", plaquette1/6./VOLUME);
    if (g_proc_id == 0) printf("\tPlaquette after inverse gauge fixing:  %.16e\n", plaquette2/6./VOLUME);
    
    /* undo trafo to source Even_s */
    dret1 = square_norm(Even_s, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_even(Even_s, g_trafo);
    dret2 = square_norm(Even_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    
    /* undo trafo to source Even_c */
    dret1 = square_norm(Even_c, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_even(Even_c, g_trafo);
    dret2 = square_norm(Even_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1);
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2); 
    
    /* undo trafo to source Odd_s */
    dret1 = square_norm(Odd_s, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_odd(Odd_s, g_trafo);
    dret2 = square_norm(Odd_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    /* undo trafo to source Odd_c */
    dret1 = square_norm(Odd_c, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_odd(Odd_c, g_trafo);
    dret2 = square_norm(Odd_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2); 
    
    
    // Even_new_s
    dret1 = square_norm(Even_new_s, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_even(Even_new_s, g_trafo);
    dret2 = square_norm(Even_new_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    // Even_new_c
    dret1 = square_norm(Even_new_c, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_even(Even_new_c, g_trafo);
    dret2 = square_norm(Even_new_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    // Odd_new_s
    dret1 = square_norm(Odd_new_s, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_odd(Odd_new_s, g_trafo);
    dret2 = square_norm(Odd_new_s, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2);
    
    // Odd_new_c
    dret1 = square_norm(Odd_new_c, VOLUME/2 , 1);
    apply_inv_gtrafo_spinor_odd(Odd_new_c, g_trafo);
    dret2 = square_norm(Odd_new_c, VOLUME/2, 1);
    if (g_proc_id == 0) printf("\tsquare norm before gauge fixing: %.16e\n", dret1); 
    if (g_proc_id == 0) printf("\tsquare norm after gauge fixing:  %.16e\n", dret2); 
    
    finalize_temporalgauge();
    
#    ifdef MPI
    xchange_gauge(g_gauge_field);
#    endif
    
  }
#  endif
#endif
  return(iter);
}
const Field Dirac_LowModeDeflation_ExactEigen::mult_dag(const Field& f)const{
  return gamma5(mult(gamma5(f)));
}
Exemplo n.º 23
0
int invert_clover_eo(spinor * const Even_new, spinor * const Odd_new,
                     spinor * const Even, spinor * const Odd,
                     const double precision, const int max_iter,
                     const int solver_flag, const int rel_prec,solver_params_t solver_params,
                     su3 *** gf, matrix_mult Qsq, matrix_mult Qm) {
    int iter;

    if(g_proc_id == 0 && g_debug_level > 0) {
        printf("# Using even/odd preconditioning!\n");
        fflush(stdout);
    }

    assign_mul_one_sw_pm_imu_inv(EE, Even_new, Even, +g_mu);

    Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even_new);
    /* The sign is plus, since in Hopping_Matrix */
    /* the minus is missing                      */
    assign_mul_add_r(g_spinor_field[DUM_DERI], +1., Odd, VOLUME/2);
    /* Do the inversion with the preconditioned  */
    /* matrix to get the odd sites               */

    /* Here we invert the hermitean operator squared */
    gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
    if(g_proc_id == 0) {
        //printf("# Using CG!\n");
        printf("# mu = %f, kappa = %f, csw = %f\n",
               g_mu/2./g_kappa, g_kappa, g_c_sw);
        fflush(stdout);
    }

    if(solver_flag == CG) {
        if(g_proc_id == 0) {
            printf("# Using CG!\n");
            fflush(stdout);
        }
        iter = cg_her(Odd_new, g_spinor_field[DUM_DERI], max_iter,
                      precision, rel_prec,
                      VOLUME/2, Qsq);
        Qm(Odd_new, Odd_new);
    } else if(solver_flag == INCREIGCG) {

        if(g_proc_id == 0) {
            printf("# Using Incremental Eig-CG!\n");
            fflush(stdout);
        }
        iter = incr_eigcg(VOLUME/2,solver_params.eigcg_nrhs, solver_params.eigcg_nrhs1, Odd_new, g_spinor_field[DUM_DERI], solver_params.eigcg_ldh, Qsq,
                          solver_params.eigcg_tolsq1, solver_params.eigcg_tolsq, solver_params.eigcg_restolsq , solver_params.eigcg_rand_guess_opt,
                          rel_prec, max_iter, solver_params.eigcg_nev, solver_params.eigcg_vmax);
        Qm(Odd_new, Odd_new);

    } else {
        if(g_proc_id == 0) {
            printf("# This solver is not available for this operator. Exisiting!\n");
            fflush(stdout);
        }
        return 0;
    }


    /* Reconstruct the even sites                */
    Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd_new);
    clover_inv(g_spinor_field[DUM_DERI], +1, g_mu);
    /* The sign is plus, since in Hopping_Matrix */
    /* the minus is missing                      */
    assign_add_mul_r(Even_new, g_spinor_field[DUM_DERI], +1., VOLUME/2);

    return(iter);
}
Exemplo n.º 24
0
void invert_overlap(const int op_id, const int index_start) {
  operator * optr;
  void (*op)(spinor*,spinor*);
  static complex alpha={0,0};
  spinorPrecWS *ws;
  optr = &operator_list[op_id];
  op=&Dov_psi;

  /* here we need to (re)compute the kernel eigenvectors */
  /* for new gauge fields                                */

  if(g_proc_id == 0) {printf("# Not using even/odd preconditioning!\n"); fflush(stdout);}
  convert_eo_to_lexic(g_spinor_field[DUM_DERI], optr->sr0, optr->sr1);
  convert_eo_to_lexic(g_spinor_field[DUM_DERI+1], optr->prop0, optr->prop1);

  if(optr->solver == 13 ){
    optr->iterations = sumr(g_spinor_field[DUM_DERI+1],g_spinor_field[DUM_DERI] , optr->maxiter, optr->eps_sq);
  } 
  else if(optr->solver == 1 /* CG */) {

    gamma5(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI], VOLUME);
  
    if(use_preconditioning==1 && g_precWS!=NULL){
      ws=(spinorPrecWS*)g_precWS;
      printf("# Using preconditioning (which one?)!\n");
    
      alpha.re=ws->precExpo[2];
      spinorPrecondition(g_spinor_field[DUM_DERI+1],g_spinor_field[DUM_DERI+1],ws,T,L,alpha,0,1);

      /* 	iter = cg_her(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], max_iter, precision,  */
      /* 		    rel_prec, VOLUME, &Q_pm_psi_prec); */
      optr->iterations = cg_her(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], optr->maxiter, optr->eps_sq,
				optr->rel_prec, VOLUME, &Qov_sq_psi_prec);
    
      alpha.re=ws->precExpo[0];
      spinorPrecondition(g_spinor_field[DUM_DERI],g_spinor_field[DUM_DERI],ws,T,L,alpha,0,1);
    
    } 
    else {
      printf("# Not using preconditioning (which one?)!\n");
      /* 	iter = cg_her(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], max_iter, precision,  */
      /* 		      rel_prec, VOLUME, &Q_pm_psi); */
      optr->iterations = cg_her(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], optr->maxiter, optr->eps_sq,
				optr->rel_prec, VOLUME, &Qov_sq_psi);
    }
  
  
    Qov_psi(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI]);
  
    if(use_preconditioning == 1 && g_precWS!=NULL){
      ws=(spinorPrecWS*)g_precWS;
      alpha.re=ws->precExpo[1];
      spinorPrecondition(g_spinor_field[DUM_DERI+1],g_spinor_field[DUM_DERI+1],ws,T,L,alpha,0,1);
    }
  
  }
  
  op(g_spinor_field[4],g_spinor_field[DUM_DERI+1]);

  convert_eo_to_lexic(g_spinor_field[DUM_DERI], optr->sr0, optr->sr1);

  optr->reached_prec=diff_and_square_norm(g_spinor_field[4],g_spinor_field[DUM_DERI],VOLUME);
  
  convert_lexic_to_eo(optr->prop0, optr->prop1 , g_spinor_field[DUM_DERI+1]);

  return;
}
Exemplo n.º 25
0
void cloverdetratio_derivative_orig(const int no, hamiltonian_field_t * const hf) {
  monomial * mnl = &monomial_list[no];

  /* This factor 2* a missing factor 2 in trace_lambda */
  mnl->forcefactor = 1.;

  /*********************************************************************
   *
   *  this is being run in case there is even/odd preconditioning
   * 
   * This term is det((Q^2 + \mu_1^2)/(Q^2 + \mu_2^2))
   * mu1 and mu2 are set according to the monomial
   *
   *********************************************************************/
  /* First term coming from the second field */
  /* Multiply with W_+ */
  g_mu = mnl->mu;
  g_mu3 = mnl->rho2; //rho2
  boundary(mnl->kappa);

  // we compute the clover term (1 + T_ee(oo)) for all sites x
  sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); 
  // we invert it for the even sites only including mu
  sw_invert(EE, mnl->mu);
  
  if(mnl->solver != CG) {
    fprintf(stderr, "Bicgstab currently not implemented, using CG instead! (detratio_monomial.c)\n");
  }
  
  mnl->Qp(g_spinor_field[DUM_DERI+2], mnl->pf);
  g_mu3 = mnl->rho; // rho1

  /* Invert Q_{+} Q_{-} */
  /* X_W -> DUM_DERI+1 */
  chrono_guess(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], mnl->csg_field, 
	       mnl->csg_index_array, mnl->csg_N, mnl->csg_n, VOLUME/2, mnl->Qsq);
  mnl->iter1 += cg_her(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], mnl->maxiter, 
		       mnl->forceprec, g_relative_precision_flag, VOLUME/2, mnl->Qsq);
  chrono_add_solution(g_spinor_field[DUM_DERI+1], mnl->csg_field, mnl->csg_index_array,
		      mnl->csg_N, &mnl->csg_n, VOLUME/2);
  /* Y_W -> DUM_DERI  */
  mnl->Qm(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);
  
  /* apply Hopping Matrix M_{eo} */
  /* to get the even sites of X */
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+1], EE, -mnl->mu);
  /* \delta Q sandwitched by Y_o^\dagger and X_e */
  deriv_Sb(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], hf, mnl->forcefactor); 
  
  /* to get the even sites of Y */
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI], EE, mnl->mu);
  /* \delta Q sandwitched by Y_e^\dagger and X_o */
  deriv_Sb(EO, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], hf, mnl->forcefactor); 

  // here comes the clover term...
  // computes the insertion matrices for S_eff
  // result is written to swp and swm
  // even/even sites sandwiched by gamma_5 Y_e and gamma_5 X_e  
  gamma5(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+2], VOLUME/2);
  sw_spinor(EO, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3]);
  
  // odd/odd sites sandwiched by gamma_5 Y_o and gamma_5 X_o
  gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
  sw_spinor(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);

  g_mu3 = mnl->rho2; // rho2
  
  /* Second term coming from the second field */
  /* The sign is opposite!! */
  mul_r(g_spinor_field[DUM_DERI], -1., mnl->pf, VOLUME/2);
  
  /* apply Hopping Matrix M_{eo} */
  /* to get the even sites of X */
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+1], EE, -mnl->mu);
  /* \delta Q sandwitched by Y_o^\dagger and X_e */
  deriv_Sb(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], hf, mnl->forcefactor); 
  
  /* to get the even sites of Y */
  H_eo_sw_inv_psi(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI], EE, mnl->mu);
  /* \delta Q sandwitched by Y_e^\dagger and X_o */
  deriv_Sb(EO, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], hf, mnl->forcefactor);

  // here comes the clover term...
  // computes the insertion matrices for S_eff
  // result is written to swp and swm
  // even/even sites sandwiched by gamma_5 Y_e and gamma_5 X_e
  gamma5(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+2], VOLUME/2);
  sw_spinor(EO, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3]);
  
  // odd/odd sites sandwiched by gamma_5 Y_o and gamma_5 X_o
  gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
  sw_spinor(OE, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);

  sw_all(hf, mnl->kappa*mnl->forcefactor, mnl->c_sw);
  
  g_mu = g_mu1;
  g_mu3 = 0.;
  boundary(g_kappa);

  return;
}
Exemplo n.º 26
0
int invert_doublet_eo(spinor * const Even_new_s, spinor * const Odd_new_s, 
                      spinor * const Even_new_c, spinor * const Odd_new_c,
                      spinor * const Even_s, spinor * const Odd_s,
                      spinor * const Even_c, spinor * const Odd_c,
                      const double precision, const int max_iter,
                      const int solver_flag, const int rel_prec, 
                      solver_params_t solver_params, const ExternalInverter external_inverter, 
                      const SloppyPrecision sloppy, const CompressionType compression) {

  int iter = 0;

#ifdef TM_USE_QUDA
  if( external_inverter==QUDA_INVERTER ) {
    return invert_doublet_eo_quda( Even_new_s, Odd_new_s, Even_new_c, Odd_new_c,
                                   Even_s, Odd_s, Even_c, Odd_c,
                                   precision, max_iter,
                                   solver_flag, rel_prec, 1,
                                   sloppy, compression );
  }
#endif
  
#ifdef HAVE_GPU
#  ifdef TEMPORALGAUGE
  if (usegpu_flag) {
    gtrafo_eo_nd(Even_s, Odd_s, Even_c, Odd_c, 
                 (spinor*const)NULL, (spinor*const)NULL, (spinor*const)NULL, (spinor*const)NULL, 
                 GTRAFO_APPLY);    
  } 
#  endif  
#endif /* HAVE_GPU*/


  /* here comes the inversion using even/odd preconditioning */
  if(g_proc_id == 0) {printf("# Using even/odd preconditioning!\n"); fflush(stdout);}
  M_ee_inv_ndpsi(Even_new_s, Even_new_c, 
                 Even_s, Even_c,
                 g_mubar, g_epsbar);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even_new_s);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI+1], Even_new_c);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_mul_add_r(g_spinor_field[DUM_DERI], +1., Odd_s, VOLUME/2);
  assign_mul_add_r(g_spinor_field[DUM_DERI+1], +1., Odd_c, VOLUME/2);
  
  /* Do the inversion with the preconditioned  */
  /* matrix to get the odd sites               */
  
  /* Here we invert the hermitean operator squared */
  
  if(g_proc_id == 0) {
    printf("# Using CG for TMWILSON flavour doublet!\n"); 
    fflush(stdout);
  }
  if ( external_inverter == NO_EXT_INV ){
    gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
    gamma5(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], VOLUME/2);
  
#ifdef HAVE_GPU
    if (usegpu_flag) {    // GPU, mixed precision solver
#    if ( defined TM_USE_MPI  && defined PARALLELT )
      iter = mixedsolve_eo_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                              max_iter, precision, rel_prec);
#    elif ( !defined TM_USE_MPI  && !defined PARALLELT )
      iter = mixedsolve_eo_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                              max_iter, precision, rel_prec);
#    else
      printf("MPI and/or PARALLELT are not appropriately set for the GPU implementation. Aborting...\n");
      exit(-1);
#    endif
    }
    else {                // CPU, conjugate gradient
      iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                       max_iter, precision, rel_prec, 
                       VOLUME/2, &Qtm_pm_ndpsi);
    }
#else                   // CPU, conjugate gradient
    if(solver_flag == RGMIXEDCG){
      iter = rg_mixed_cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                                solver_params, max_iter, precision, rel_prec, VOLUME/2,
                                &Qtm_pm_ndpsi, &Qtm_pm_ndpsi_32);
    } 
    else {
      iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                       max_iter, precision, rel_prec, VOLUME/2, &Qtm_pm_ndpsi);
    }
#endif
    Qtm_dagger_ndpsi(Odd_new_s, Odd_new_c,
                     Odd_new_s, Odd_new_c);
  } // if(NO_EXT_INV)
#ifdef TM_USE_QPHIX
  else if (external_inverter == QPHIX_INVERTER ) {
    // using QPhiX, we invert M M^dagger y = b, so we don't need gamma_5 multiplications
    iter = invert_eo_qphix_twoflavour(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                                      max_iter, precision, solver_flag, rel_prec,
                                      solver_params, sloppy, compression);
    // and it multiplies y internally by M^dagger, returning M^{-1} b as required
  }
#endif // TM_USE_QPHIX

  /* Reconstruct the even sites                */
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd_new_s);
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI+1], Odd_new_c);
  M_ee_inv_ndpsi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3],
                 g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                 g_mubar, g_epsbar);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_add_mul_r(Even_new_s, g_spinor_field[DUM_DERI+2], +1., VOLUME/2);
  assign_add_mul_r(Even_new_c, g_spinor_field[DUM_DERI+3], +1., VOLUME/2);
  
  
#ifdef HAVE_GPU  
  /* return from temporal gauge again */
#  ifdef TEMPORALGAUGE
  if (usegpu_flag) { 
    gtrafo_eo_nd(Even_s, Odd_s, Even_c, Odd_c, Even_new_s, Odd_new_s, Even_new_c, Odd_new_c,
                 GTRAFO_REVERT);
  }
#  endif
#endif
  return(iter);
}
Exemplo n.º 27
0
int invert_cloverdoublet_eo(spinor * const Even_new_s, spinor * const Odd_new_s, 
                      spinor * const Even_new_c, spinor * const Odd_new_c,
                      spinor * const Even_s, spinor * const Odd_s,
                      spinor * const Even_c, spinor * const Odd_c,
                      const double precision, const int max_iter,
                      const int solver_flag, const int rel_prec, solver_params_t solver_params,
                      const ExternalInverter external_inverter, const SloppyPrecision sloppy, const CompressionType compression) {
  
  int iter = 0;

#ifdef TM_USE_QUDA
  if( external_inverter==QUDA_INVERTER ) {
    return invert_doublet_eo_quda( Even_new_s, Odd_new_s, Even_new_c, Odd_new_c,
                                   Even_s, Odd_s, Even_c, Odd_c,
                                   precision, max_iter,
                                   solver_flag, rel_prec, 1,
                                   sloppy, compression );
  }
#endif
  
  /* here comes the inversion using even/odd preconditioning */
  if(g_proc_id == 0) {printf("# Using even/odd preconditioning!\n"); fflush(stdout);}
  Msw_ee_inv_ndpsi(Even_new_s, Even_new_c, 
                  Even_s, Even_c);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI], Even_new_s);
  Hopping_Matrix(OE, g_spinor_field[DUM_DERI+1], Even_new_c);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_mul_add_r(g_spinor_field[DUM_DERI], +1., Odd_s, VOLUME/2);
  assign_mul_add_r(g_spinor_field[DUM_DERI+1], +1., Odd_c, VOLUME/2);  
  if( external_inverter == NO_EXT_INV ){    
    /* Do the inversion with the preconditioned  */
    /* matrix to get the odd sites               */
    
    /* Here we invert the hermitean operator squared */
    
    if(g_proc_id == 0) {
      printf("# Using CG for TMWILSON flavour doublet!\n"); 
      fflush(stdout);
    }
    gamma5(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], VOLUME/2);
    gamma5(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], VOLUME/2);
    
    if(solver_flag == RGMIXEDCG){
      iter = rg_mixed_cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                                solver_params, max_iter, precision, rel_prec, VOLUME/2,
                                &Qsw_pm_ndpsi, &Qsw_pm_ndpsi_32);
    } else {
      iter = cg_her_nd(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                                  max_iter, precision, rel_prec, 
                                  VOLUME/2, &Qsw_pm_ndpsi);
    }
    
    Qsw_dagger_ndpsi(Odd_new_s, Odd_new_c,
                    Odd_new_s, Odd_new_c);
  } // if(NO_EXT_INV)
#ifdef TM_USE_QPHIX
  else if (external_inverter == QPHIX_INVERTER ) {
    // using QPhiX, we invert M M^dagger y = b, so we don't need gamma_5 multiplications
    iter = invert_eo_qphix_twoflavour(Odd_new_s, Odd_new_c, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1],
                                      max_iter, precision, solver_flag, rel_prec,
                                      solver_params, sloppy, compression);
    // and it multiplies y internally by M^dagger, returning M^{-1} b as required
  }
#endif // TM_USE_QPHIX
  
  /* Reconstruct the even sites                */
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI], Odd_new_s);
  Hopping_Matrix(EO, g_spinor_field[DUM_DERI+1], Odd_new_c);
  Msw_ee_inv_ndpsi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3],
                   g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]);
  
  /* The sign is plus, since in Hopping_Matrix */
  /* the minus is missing                      */
  assign_add_mul_r(Even_new_s, g_spinor_field[DUM_DERI+2], +1., VOLUME/2);
  assign_add_mul_r(Even_new_c, g_spinor_field[DUM_DERI+3], +1., VOLUME/2);
  
  return(iter);
}
Exemplo n.º 28
0
/* Check GW relation with operator norm over the full lattice */
void ov_check_ginsparg_wilson_relation_strong(void) {

  double norm_diff, norm_left, norm_right, norm, max_rel = 0.0, min_left = 1.0e100, min_right = 1.0e100,  max_diff = 0.0, min_norm = 1.0e100;
  int x, y, z, t, i, j, k;
  spinor *S_left[4][3], *S_right[4][3], *S_diff[4][3];

  if (g_debug_level>0) {
    printf("// creating spinor fields and calculating {gamma_5,D} psi and a D gamma_5 D psi\n");
    fflush(stdout);
  }
  for (i=0; i<4; i++)
    for (j=0; j<3; j++) {
			
      if (g_debug_level>1) {
	printf("// spinor field: delta_dirac at %d, delta_color at %d\n", i, j);
	fflush(stdout);
      }
			
      /* get memory for the spinor */
      S_left[i][j]  = ov_alloc_spinor();
      S_right[i][j] = ov_alloc_spinor();
      S_diff[i][j]  = ov_alloc_spinor();

      /* Create delta source at origin */
      source_spinor_field(g_spinor_field[1], g_spinor_field[0], i, j);
      convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]);

      /* S_right = D gamma_5 D psi */
      Dov_psi(g_spinor_field[3], g_spinor_field[2]);
      gamma5(S_left[i][j], g_spinor_field[3], VOLUME);
      Dov_psi(S_right[i][j], S_left[i][j]);

      /* S_left = {gamma_5, D} psi */
      gamma5(g_spinor_field[3], g_spinor_field[2], VOLUME);
      Dov_psi(g_spinor_field[4], g_spinor_field[3]);
      add(S_left[i][j], S_left[i][j], g_spinor_field[4], VOLUME);

      /* S_diff = (S_left-S_right) psi, should be zero (GW relation) */
      diff(S_diff[i][j], S_left[i][j], S_right[i][j], VOLUME);
    }

  /* scan the whole lattice and check GW relation */
  printf("// test of the Ginsparg-Wilson relation:\n");
  if (g_debug_level>0)
    fflush(stdout);
  for(x=0; x<LX; x++)
    for(y = 0; y < LY; y++)
      for(z = 0; z < LZ; z++)
	for(t = 0; t < T; t++) {
	  k = g_ipt[t][x][y][z];
	  norm_diff  = ov_operator_colsumnorm(S_diff, k);
	  norm_left  = ov_operator_colsumnorm(S_left, k);
	  norm_right = ov_operator_colsumnorm(S_right, k);
	  norm = (norm_left+norm_right)/2.;
	  if (norm < min_norm)
	    min_norm = norm;
	  if (norm > 0.0) {
	    norm = norm_diff/norm;
	    if (norm > max_rel)
	      max_rel = norm;
	    if ((norm > 1.8) && (g_debug_level)>=5) {
	      printf("(%d,%d,%d,%d): taxi = %d, rel = %.20le, lr = [%.4le, %.4le], diff = %.4le\n", t, x, y, z, ((x>LX/2) ? LX-x : x)+((y>LY/2) ? LY-y : y)+((z>LZ/2) ? LZ-z : z)+((t>T/2) ? T-t : t), norm, norm_left, norm_right, norm_diff);
	      printf("// left[0][0]:\n");
	      ov_print_spinor(&S_left[0][0][k]);
	      printf("// right[0][0]:\n");
	      ov_print_spinor(&S_right[0][0][k]);
	      printf("// diff[0][0]:\n");
	      ov_print_spinor(&S_diff[0][0][k]);
	    }
	  }
	  if (norm_left < min_left)
	    min_left = norm_left;
	  if (norm_right < min_right)
	    min_right = norm_right;
	  if (norm_diff > max_diff)
	    max_diff = norm_diff;
	}

  /* print results */
  printf(" - maximum absolute deviation: %.4le\n", max_diff);
  printf(" - maximum relative deviation: %.4le\n", max_rel);
  printf(" - minimum mean norm: %.4le\n", min_norm);
  printf(" - minimum norm {gamma_5, D}: %.4le\n", min_left);
  printf(" - minimum norm D gamma_5 D: %.4le\n", min_right);

  /* free memory */
  for (i=0; i<4; i++)
    for (j=0; j<3; j++) {
      ov_free_spinor(S_left[i][j]);
      ov_free_spinor(S_right[i][j]);
      ov_free_spinor(S_diff[i][j]);
    }
}