Exemple #1
0
double ndpoly_acc(const int id) {
  int j, ij=0;
  double temp, sgn, fact, Diff;
  double Ener[8];
  double factor[8];
  monomial * mnl = &monomial_list[id];
  spinor *up0, *dn0, *up1, *dn1, *dummy;

  mnl->energy1 = 0.;
  Ener[0] = 0;
  factor[0] = 1.0;
  for(j = 1; j < 8; j++){
    factor[j] = j*factor[j-1];
    Ener[j] = 0;
  }
  /* IF PHMC */
  up0 = g_chi_up_spinor_field[0];
  up1 = g_chi_up_spinor_field[1];
  dn0 = g_chi_dn_spinor_field[0];
  dn1 = g_chi_dn_spinor_field[1];
  /* This is needed if we consider only "1" in eq. 9 */
  assign(up0, mnl->pf , VOLUME/2);
  assign(dn0, mnl->pf2, VOLUME/2);

  if(phmc_exact_poly==0) {
    for(j = 1; j <= (phmc_dop_n_cheby-1); j++) {
      /* Change this name !!*/
      Q_tau1_min_cconst_ND(up1, dn1, up0, dn0, phmc_root[j-1]);

      dummy = up1; up1 = up0; up0 = dummy;
      dummy = dn1; dn1 = dn0; dn0 = dummy;
      /* result always in up0 and dn0 */
    }
  
    ij=0;
    if(up0 != g_chi_up_spinor_field[ij]) {
      assign(g_chi_up_spinor_field[ij], up0, VOLUME/2);
      assign(g_chi_dn_spinor_field[ij], dn0, VOLUME/2);
    }

    temp = square_norm(g_chi_up_spinor_field[ij], VOLUME/2, 1);
    Ener[ij] = temp;

    temp = square_norm(g_chi_dn_spinor_field[ij], VOLUME/2, 1);
    Ener[ij] += temp;

    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      printf("PHMC: Here comes the computation of H_new with \n \n");

      printf("PHMC: At j=%d  PHMC Final Energy %e \n", ij, mnl->energy1+Ener[ij]);
      printf("PHMC: At j=%d  PHMC Only Final Energy %e \n", ij, Ener[ij]);
    }
    
    /* Here comes the loop for the evaluation of A, A^2, ...  */
    for(j = 1; j < 1; j++){ /* To omit corrections just set  j<1 */
      
      if(j % 2){ /*  Chi[j] = ( Qdag P  Ptilde ) Chi[j-1]  */ 
	Poly_tilde_ND(g_chi_up_spinor_field[j], g_chi_dn_spinor_field[j], 
		      phmc_ptilde_cheby_coef, phmc_ptilde_n_cheby, 
		      g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1]);
	QdaggerQ_poly(g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1], 
		      phmc_dop_cheby_coef, phmc_dop_n_cheby, 
		      g_chi_up_spinor_field[j], g_chi_dn_spinor_field[j]);
	QdaggerNon_degenerate(g_chi_up_spinor_field[j], g_chi_dn_spinor_field[j], 
			      g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1]);
      }
      else { /*  Chi[j] = ( Ptilde P Q ) Chi[j-1]  */ 
	QNon_degenerate(g_chi_up_spinor_field[j], g_chi_dn_spinor_field[j], 
			g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1]);
	QdaggerQ_poly(g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1], 
		      phmc_dop_cheby_coef, phmc_dop_n_cheby, g_chi_up_spinor_field[j], 
		      g_chi_dn_spinor_field[j]);
	Poly_tilde_ND(g_chi_up_spinor_field[j], g_chi_dn_spinor_field[j], 
		      phmc_ptilde_cheby_coef, phmc_ptilde_n_cheby, 
		      g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1]);
      }

      Ener[j] = Ener[j-1] + Ener[0];
      sgn = -1.0;
      for(ij = 1; ij < j; ij++){
	fact = factor[j] / (factor[ij] * factor[j-ij]);
	if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
	  printf("PHMC: Here  j=%d  and  ij=%d   sign=%f  fact=%f \n", j ,ij, sgn, fact);
	}
	Ener[j] += sgn*fact*Ener[ij];
	sgn = -sgn;
      }
      temp = square_norm(g_chi_up_spinor_field[j], VOLUME/2, 1);
      temp += square_norm(g_chi_dn_spinor_field[j], VOLUME/2, 1);
      if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
	printf("PHMC: Here  j=%d   sign=%f  temp=%e \n", j, sgn, temp);
      }

      Ener[j] += sgn*temp;

      Diff = fabs(Ener[j] - Ener[j-1]);
      if((g_proc_id == g_stdio_proc) && (g_debug_level > 0)) {
	printf("PHMC: Correction aftern %d steps: %e \n", j, Diff);
      }

      if(Diff < g_acc_Hfin) {
	if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
	  printf("PHMC: At j = %d  PHMC Only Final Energy %e \n", j, Ener[j]);
	}
	break;
      }
    }
    mnl->energy1 += Ener[ij];  /* this is quite sticky */
    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      printf("PHMC: At j = %d  P=%e +HMC Final Energy %e \n\n", ij, Ener[ij], mnl->energy1);
    }
  } 
  else if(phmc_exact_poly==1 && g_epsbar!=0.0) {
    /* B(Q*tau1) */
    for(j = 1; j <= (phmc_dop_n_cheby-1); j++){
      Q_tau1_min_cconst_ND(up1, dn1, up0, dn0, phmc_root[j-1]);

      dummy = up1; up1 = up0; up0 = dummy;
      dummy = dn1; dn1 = dn0; dn0 = dummy;
      /* result always in up0 and dn0 */
    }
    if(up0 != g_chi_up_spinor_field[0]) {
      assign(g_chi_up_spinor_field[0], up0, VOLUME/2);
      assign(g_chi_dn_spinor_field[0], dn0, VOLUME/2);
    }

    temp = square_norm(g_chi_up_spinor_field[0], VOLUME/2, 1);
    Ener[0] = temp;

    temp = square_norm(g_chi_dn_spinor_field[0], VOLUME/2, 1);
    Ener[0] += temp;

    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      ij=0;
      printf("PHMC: Here comes the computation of H_new with \n \n");
      printf("PHMC: At j=%d  P+HMC Final Energy %e \n", ij, mnl->energy1+Ener[0]);
      printf("PHMC: At j=%d  PHMC Only Final Energy %e \n", ij, Ener[0]);
    }

    mnl->energy1 += Ener[0];
    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      printf("PHMC: At j = %d  P=%e +HMC Final Energy %e \n\n", ij, Ener[0], mnl->energy1);
    }
  } 
  else if(phmc_exact_poly == 1 && g_epsbar == 0.0) {
    for(j = 1; j < (phmc_dop_n_cheby); j++) {
      assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2);
      Qtm_pm_min_cconst_nrm(g_chi_up_spinor_field[1],
			    g_chi_up_spinor_field[0],
			    phmc_root[j-1]);
    }
    assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2);

    temp = square_norm(g_chi_up_spinor_field[0], VOLUME/2, 1);
    Ener[0] = temp;

    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      printf("PHMC: Here comes the computation of H_new with \n \n");
      printf("PHMC: At j=%d  P+HMC Final Energy %e \n", ij, mnl->energy1+Ener[0]);
      printf("PHMC: At j=%d  PHMC Only Final Energy %e \n", ij, Ener[0]);
    }

    mnl->energy1 += Ener[0];
    if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) {
      printf("PHMC: At j = %d  P=%e +HMC Final Energy %e \n\n", ij, Ener[0], mnl->energy1);
    }
  }

  if(g_proc_id == 0 && g_debug_level > 3) {
    printf("called ndpoly_acc for id %d %d dH = %1.4e\n", id, g_running_phmc, mnl->energy1 - mnl->energy0);
  }
  /* END IF PHMC */
  return(mnl->energy1 - mnl->energy0);
}
Exemple #2
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_gauge_action();
      apply_gtrafo(g_gauge_field, g_trafo);								// transformation of the gauge field
      plaquette2 = measure_gauge_action();
      	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();
      #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_ND(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);
  
  
  #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, &Q_Qdagger_ND);
    }
  #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, &Q_Qdagger_ND);
  #endif
  
  
  QdaggerNon_degenerate(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_ND(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);
  
  
  #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_gauge_action();
      copy_gauge_field(g_gauge_field, g_tempgauge_field);
      g_update_gauge_copy = 1;
      plaquette2 = measure_gauge_action();
      	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();
      #endif
      
    }
  #endif
  #endif


  return(iter);
}