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); }
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); }