void cloverdet_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; g_mu = mnl->mu; g_mu3 = mnl->rho; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term(hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, mnl->mu); random_spinor_field(g_spinor_field[2], VOLUME/2, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[2], VOLUME/2, 1); mnl->Qp(mnl->pf, g_spinor_field[2]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); g_mu = g_mu1; g_mu3 = 0.; boundary(g_kappa); if(g_proc_id == 0 && g_debug_level > 3) { printf("called cloverdet_heatbath for id %d %d\n", id, mnl->even_odd_flag); } return; }
int init_operators() { static int oinit = 0; operator * optr; if(!oinit) { oinit = 1; for(int i = 0; i < no_operators; i++) { optr = operator_list + i; /* This is a hack, it should be set on an operator basis. */ optr->rel_prec = g_relative_precision_flag; if(optr->type == TMWILSON || optr->type == WILSON) { if(optr->c_sw > 0) { init_sw_fields(); } if(optr->even_odd_flag) { optr->applyQp = &Qtm_plus_psi; optr->applyQm = &Qtm_minus_psi; optr->applyQsq = &Qtm_pm_psi; optr->applyMp = &Mtm_plus_psi; optr->applyMm = &Mtm_minus_psi; } else { optr->applyQp = &Q_plus_psi; optr->applyQm = &Q_minus_psi; optr->applyQsq = &Q_pm_psi; optr->applyMp = &D_psi; optr->applyMm = &D_psi; } if(optr->solver == 12) { if (g_cart_id == 0 && optr->even_odd_flag == 1) fprintf(stderr, "CG Multiple mass solver works only without even/odd! Forcing!\n"); optr->even_odd_flag = 0; if (g_cart_id == 0 && optr->DownProp) fprintf(stderr, "CGMMS doesn't need AddDownPropagator! Switching Off!\n"); optr->DownProp = 0; } } else if(optr->type == OVERLAP) { optr->even_odd_flag = 0; optr->applyM = &Dov_psi; optr->applyQ = &Qov_psi; } else if(optr->type == DBTMWILSON) { optr->even_odd_flag = 1; optr->applyDbQsq = &Qtm_pm_ndpsi; /* TODO: this should be here! */ /* Chi`s-spinors memory allocation */ /* if(init_chi_spinor_field(VOLUMEPLUSRAND/2, 20) != 0) { */ /* fprintf(stderr, "Not enough memory for 20 NDPHMC Chi fields! Aborting...\n"); */ /* exit(0); */ /* } */ } else if(optr->type == DBCLOVER) { optr->even_odd_flag = 1; optr->applyDbQsq = &Qtm_pm_ndpsi; } } } return(0); }
void cloverndpoly_heatbath(const int id, hamiltonian_field_t * const hf) { int j; monomial * mnl = &monomial_list[id]; spinor *up0, *dn0, *up1, *dn1, *dummy; double atime, etime; atime = gettime(); ndpoly_set_global_parameter(mnl, 0); g_mu3 = 0.; init_sw_fields(); sw_term((const su3**)hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert_nd(mnl->mubar*mnl->mubar - mnl->epsbar*mnl->epsbar); // we measure before trajectory! if((mnl->rec_ev != 0) && (hf->traj_counter%mnl->rec_ev == 0)) { phmc_compute_ev(hf->traj_counter-1, id, &Qsw_pm_ndbipsi); } mnl->energy0 = 0.; random_spinor_field_eo(g_chi_up_spinor_field[0], mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(g_chi_up_spinor_field[0], VOLUME/2, 1); random_spinor_field_eo(g_chi_dn_spinor_field[0], mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(g_chi_dn_spinor_field[0], VOLUME/2, 1); Qsw_ndpsi(g_chi_up_spinor_field[1], g_chi_dn_spinor_field[1], g_chi_up_spinor_field[0], g_chi_dn_spinor_field[0]); 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]; for(j = 1; j < (mnl->MDPolyDegree); j++){ Qsw_tau1_sub_const_ndpsi(up0, dn0, up1, dn1, mnl->MDPolyRoots[mnl->MDPolyDegree-2+j]); dummy = up1; up1 = up0; up0 = dummy; dummy = dn1; dn1 = dn0; dn0 = dummy; } Ptilde_ndpsi(up0, dn0, mnl->PtildeCoefs, mnl->PtildeDegree, up1, dn1, &Qsw_pm_ndpsi); assign(mnl->pf, up0, VOLUME/2); assign(mnl->pf2, dn0, VOLUME/2); etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called cloverndpoly_heatbath for id %d energy %f\n", id, mnl->energy0); } } return; }
void clover_trlog_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; mnl->energy0 = 0.; init_sw_fields(); sw_term(hf->gaugefield, mnl->kappa, mnl->c_sw); /*compute the contribution from the clover trlog term */ mnl->energy0 = -sw_trace(EO, mnl->mu); if(g_proc_id == 0 && g_debug_level > 3) { printf("called clover_trlog_heatbath for id %d E = %e\n", id, mnl->energy0); } return; }
double cloverdetratio_rwacc(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; int save_sloppy = g_sloppy_precision_flag; double atime, etime; atime = gettime(); g_mu = mnl->mu2; boundary(mnl->kappa2); init_sw_fields(); sw_term( (const su3**) hf->gaugefield, mnl->kappa2, mnl->c_sw); sw_invert(EE, mnl->mu2); g_mu3 = 0.; mnl->Qp(mnl->w_fields[1], mnl->pf); g_mu3 = 0.; g_mu = mnl->mu; boundary(mnl->kappa); sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, mnl->mu); chrono_guess(mnl->w_fields[0], mnl->w_fields[1], mnl->csg_field, mnl->csg_index_array, mnl->csg_N, mnl->csg_n, VOLUME/2, &Qtm_plus_psi); g_sloppy_precision_flag = 0; mnl->iter0 += solve_degenerate(mnl->w_fields[0], mnl->w_fields[1], mnl->solver_params, mnl->maxiter, mnl->accprec, g_relative_precision_flag, VOLUME/2, mnl->Qsq, mnl->solver); mnl->Qm(mnl->w_fields[0], mnl->w_fields[0]); g_sloppy_precision_flag = save_sloppy; /* Compute the energy contr. from second field */ mnl->energy1 = square_norm(mnl->w_fields[0], VOLUME/2, 1); g_mu = g_mu1; g_mu3 = 0.; boundary(g_kappa); etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial rwacc step: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called cloverdetratio_rwacc for id %d dH = %1.10e\n", id, mnl->energy1 - mnl->energy0); } } return(mnl->energy1 - mnl->energy0); }
void cloverdet_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; double atime, etime; atime = gettime(); int N = VOLUME/2; g_mu = mnl->mu; g_mu3 = mnl->rho; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); if(!mnl->even_odd_flag) { N = VOLUME; random_spinor_field_lexic(mnl->w_fields[0], mnl->rngrepro, RN_GAUSS); } else { sw_invert(EE, mnl->mu); random_spinor_field_eo(mnl->w_fields[0], mnl->rngrepro, RN_GAUSS); } mnl->energy0 = square_norm(mnl->w_fields[0], N, 1); mnl->Qp(mnl->pf, mnl->w_fields[0]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, N); g_mu = g_mu1; g_mu3 = 0.; boundary(g_kappa); etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called cloverdet_heatbath for id %d energy %f\n", id, mnl->energy0); } } return; }
void cloverdetratio_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; g_mu = mnl->mu; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, mnl->mu); random_spinor_field(g_spinor_field[4], VOLUME/2, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[4], VOLUME/2, 1); g_mu3 = mnl->rho; mnl->Qp(g_spinor_field[3], g_spinor_field[4]); g_mu3 = mnl->rho2; zero_spinor_field(mnl->pf,VOLUME/2); mnl->iter0 = cg_her(mnl->pf, g_spinor_field[3], mnl->maxiter, mnl->accprec, g_relative_precision_flag, VOLUME/2, mnl->Qsq); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); mnl->Qm(mnl->pf, mnl->pf); if(g_proc_id == 0 && g_debug_level > 3) { printf("called cloverdetratio_heatbath for id %d \n", id); } g_mu3 = 0.; g_mu = g_mu1; boundary(g_kappa); return; }
void op_invert(const int op_id, const int index_start, const int write_prop) { operator * optr = &operator_list[op_id]; double atime = 0., etime = 0., nrm1 = 0., nrm2 = 0.; int i; optr->iterations = 0; optr->reached_prec = -1.; g_kappa = optr->kappa; boundary(g_kappa); atime = gettime(); if(optr->type == TMWILSON || optr->type == WILSON || optr->type == CLOVER) { g_mu = optr->mu; g_c_sw = optr->c_sw; if(optr->type == CLOVER) { if (g_cart_id == 0 && g_debug_level > 1) { printf("#\n# csw = %e, computing clover leafs\n", g_c_sw); } init_sw_fields(VOLUME); sw_term( (const su3**) g_gauge_field, optr->kappa, optr->c_sw); /* this must be EE here! */ /* to match clover_inv in Qsw_psi */ sw_invert(EE, optr->mu); } for(i = 0; i < 2; i++) { if (g_cart_id == 0) { printf("#\n# 2 kappa mu = %e, kappa = %e, c_sw = %e\n", g_mu, g_kappa, g_c_sw); } if(optr->type != CLOVER) { if(use_preconditioning){ g_precWS=(void*)optr->precWS; } else { g_precWS=NULL; } optr->iterations = invert_eo( optr->prop0, optr->prop1, optr->sr0, optr->sr1, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec, 0, optr->even_odd_flag,optr->no_extra_masses, optr->extra_masses, optr->id ); /* check result */ M_full(g_spinor_field[4], g_spinor_field[5], optr->prop0, optr->prop1); } else { optr->iterations = invert_clover_eo(optr->prop0, optr->prop1, optr->sr0, optr->sr1, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec, &g_gauge_field, &Qsw_pm_psi, &Qsw_minus_psi); /* check result */ Msw_full(g_spinor_field[4], g_spinor_field[5], optr->prop0, optr->prop1); } diff(g_spinor_field[4], g_spinor_field[4], optr->sr0, VOLUME / 2); diff(g_spinor_field[5], g_spinor_field[5], optr->sr1, VOLUME / 2); nrm1 = square_norm(g_spinor_field[4], VOLUME / 2, 1); nrm2 = square_norm(g_spinor_field[5], VOLUME / 2, 1); optr->reached_prec = nrm1 + nrm2; /* convert to standard normalisation */ /* we have to mult. by 2*kappa */ if (optr->kappa != 0.) { mul_r(optr->prop0, (2*optr->kappa), optr->prop0, VOLUME / 2); mul_r(optr->prop1, (2*optr->kappa), optr->prop1, VOLUME / 2); } if (optr->solver != CGMMS && write_prop) /* CGMMS handles its own I/O */ optr->write_prop(op_id, index_start, i); if(optr->DownProp) { optr->mu = -optr->mu; } else break; } } else if(optr->type == DBTMWILSON || optr->type == DBCLOVER) { g_mubar = optr->mubar; g_epsbar = optr->epsbar; g_c_sw = 0.; if(optr->type == DBCLOVER) { g_c_sw = optr->c_sw; if (g_cart_id == 0 && g_debug_level > 1) { printf("#\n# csw = %e, computing clover leafs\n", g_c_sw); } init_sw_fields(VOLUME); sw_term( (const su3**) g_gauge_field, optr->kappa, optr->c_sw); sw_invert_nd(optr->mubar*optr->mubar-optr->epsbar*optr->epsbar); } for(i = 0; i < SourceInfo.no_flavours; i++) { if(optr->type != DBCLOVER) { optr->iterations = invert_doublet_eo( optr->prop0, optr->prop1, optr->prop2, optr->prop3, optr->sr0, optr->sr1, optr->sr2, optr->sr3, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec); } else { optr->iterations = invert_cloverdoublet_eo( optr->prop0, optr->prop1, optr->prop2, optr->prop3, optr->sr0, optr->sr1, optr->sr2, optr->sr3, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec); } g_mu = optr->mubar; if(optr->type != DBCLOVER) { M_full(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], optr->prop0, optr->prop1); } else { Msw_full(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], optr->prop0, optr->prop1); } assign_add_mul_r(g_spinor_field[DUM_DERI+1], optr->prop2, -optr->epsbar, VOLUME/2); assign_add_mul_r(g_spinor_field[DUM_DERI+2], optr->prop3, -optr->epsbar, VOLUME/2); g_mu = -g_mu; if(optr->type != DBCLOVER) { M_full(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+4], optr->prop2, optr->prop3); } else { Msw_full(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+4], optr->prop2, optr->prop3); } assign_add_mul_r(g_spinor_field[DUM_DERI+3], optr->prop0, -optr->epsbar, VOLUME/2); assign_add_mul_r(g_spinor_field[DUM_DERI+4], optr->prop1, -optr->epsbar, VOLUME/2); diff(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], optr->sr0, VOLUME/2); diff(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+2], optr->sr1, VOLUME/2); diff(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+3], optr->sr2, VOLUME/2); diff(g_spinor_field[DUM_DERI+4], g_spinor_field[DUM_DERI+4], optr->sr3, VOLUME/2); nrm1 = square_norm(g_spinor_field[DUM_DERI+1], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+2], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+3], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+4], VOLUME/2, 1); optr->reached_prec = nrm1; g_mu = g_mu1; /* For standard normalisation */ /* we have to mult. by 2*kappa */ mul_r(g_spinor_field[DUM_DERI], (2*optr->kappa), optr->prop0, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+1], (2*optr->kappa), optr->prop1, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+2], (2*optr->kappa), optr->prop2, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+3], (2*optr->kappa), optr->prop3, VOLUME/2); /* the final result should be stored in the convention used in */ /* hep-lat/0606011 */ /* this requires multiplication of source with */ /* (1+itau_2)/sqrt(2) and the result with (1-itau_2)/sqrt(2) */ mul_one_pm_itau2(optr->prop0, optr->prop2, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], -1., VOLUME/2); mul_one_pm_itau2(optr->prop1, optr->prop3, g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+3], -1., VOLUME/2); /* write propagator */ if(write_prop) optr->write_prop(op_id, index_start, i); mul_r(optr->prop0, 1./(2*optr->kappa), g_spinor_field[DUM_DERI], VOLUME/2); mul_r(optr->prop1, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+1], VOLUME/2); mul_r(optr->prop2, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+2], VOLUME/2); mul_r(optr->prop3, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+3], VOLUME/2); /* mirror source, but not for volume sources */ if(i == 0 && SourceInfo.no_flavours == 2 && SourceInfo.type != 1) { if (g_cart_id == 0) { fprintf(stdout, "# Inversion done in %d iterations, squared residue = %e!\n", optr->iterations, optr->reached_prec); } mul_one_pm_itau2(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], optr->sr0, optr->sr2, -1., VOLUME/2); mul_one_pm_itau2(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+3], optr->sr1, optr->sr3, -1., VOLUME/2); mul_one_pm_itau2(optr->sr0, optr->sr2, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI], +1., VOLUME/2); mul_one_pm_itau2(optr->sr1, optr->sr3, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], +1., VOLUME/2); } /* volume sources need only one inversion */ else if(SourceInfo.type == 1) i++; } } else if(optr->type == OVERLAP) { g_mu = 0.; m_ov=optr->m; eigenvalues(&optr->no_ev, 5000, optr->ev_prec, 0, optr->ev_readwrite, nstore, optr->even_odd_flag); /* ov_check_locality(); */ /* index_jd(&optr->no_ev_index, 5000, 1.e-12, optr->conf_input, nstore, 4); */ ov_n_cheby=optr->deg_poly; if(use_preconditioning==1) g_precWS=(void*)optr->precWS; else g_precWS=NULL; if(g_debug_level > 3) ov_check_ginsparg_wilson_relation_strong(); invert_overlap(op_id, index_start); if(write_prop) optr->write_prop(op_id, index_start, 0); } etime = gettime(); if (g_cart_id == 0 && g_debug_level > 0) { fprintf(stdout, "# Inversion done in %d iterations, squared residue = %e!\n", optr->iterations, optr->reached_prec); fprintf(stdout, "# Inversion done in %1.2e sec. \n", etime - atime); } return; }
void ndratcor_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; double atime, etime, delta; spinor * up0, * dn0, * up1, * dn1, * tup, * tdn, * Zup, * Zdn; double coefs[6] = {1./4., -3./32., 7./128., -77./2048., 231./8192., -1463./65536.}; // series of (1+x)^(1/4) double coefs_check[6] = {1./2., -1./8., 1./16., -5./128., 7./256., -21./1024.}; // series of (1+x)^(1/2) atime = gettime(); nd_set_global_parameter(mnl); g_mu3 = 0.; mnl->iter0 = 0; if(mnl->type == NDCLOVERRATCOR) { init_sw_fields(); sw_term((const su3**)hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert_nd(mnl->mubar*mnl->mubar - mnl->epsbar*mnl->epsbar); copy_32_sw_fields(); } // we measure before the trajectory! if((mnl->rec_ev != 0) && (hf->traj_counter%mnl->rec_ev == 0)) { if(mnl->type != NDCLOVERRAT) phmc_compute_ev(hf->traj_counter-1, id, &Qtm_pm_ndbipsi); else phmc_compute_ev(hf->traj_counter-1, id, &Qsw_pm_ndbipsi); } // the Gaussian distributed random fields mnl->energy0 = 0.; random_spinor_field_eo(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, VOLUME/2, 1); random_spinor_field_eo(mnl->pf2, mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(mnl->pf2, VOLUME/2, 1); mnl->solver_params.max_iter = mnl->maxiter; mnl->solver_params.squared_solver_prec = mnl->accprec; mnl->solver_params.no_shifts = mnl->rat.np; mnl->solver_params.shifts = mnl->rat.mu; mnl->solver_params.type = mnl->solver; mnl->solver_params.M_ndpsi = &Qtm_pm_ndpsi; mnl->solver_params.M_ndpsi32 = &Qtm_pm_ndpsi_32; if(mnl->type == NDCLOVERRATCOR) { mnl->solver_params.M_ndpsi = &Qsw_pm_ndpsi; mnl->solver_params.M_ndpsi32 = &Qsw_pm_ndpsi_32; } mnl->solver_params.sdim = VOLUME/2; mnl->solver_params.rel_prec = g_relative_precision_flag; // apply B to the random field to generate pseudo-fermion fields up0 = mnl->w_fields[0]; dn0 = mnl->w_fields[1]; up1 = mnl->w_fields[2]; dn1 = mnl->w_fields[3]; Zup = mnl->w_fields[4]; Zdn = mnl->w_fields[5]; apply_Z_ndpsi(up0, dn0, mnl->pf, mnl->pf2, id, hf, &(mnl->solver_params)); // computing correction to energy1 delta = coefs_check[0]*(scalar_prod_r(mnl->pf, up0, VOLUME/2, 1) + scalar_prod_r(mnl->pf2, dn0, VOLUME/2, 1)); if(g_debug_level > 2 && g_proc_id == 0) printf("# NDRATCOR heatbath: c_%d*(R * Z^%d * R) = %e\n", 1, 1, delta); // debug for showing that the old check was giving a smaller delta if(g_debug_level > 3) { double delta_old = square_norm(up0, VOLUME/2, 1) + square_norm(dn0, VOLUME/2, 1); if(g_proc_id == 0) { printf("# NDRATCOR old check: || Z^%d * R ||^2 = %e\n", 1, delta_old); printf("# NDRATCOR new check: (c_%d*(R * Z^%d * R))^2 = %e\n", 1, 1, delta*delta); } } if(delta*delta > mnl->accprec) { assign_add_mul_r(mnl->pf, up0, coefs[0], VOLUME/2); assign_add_mul_r(mnl->pf2, dn0, coefs[0], VOLUME/2); // saving first application assign(Zup, up0, VOLUME/2); assign(Zdn, dn0, VOLUME/2); for(int i = 2; i < 8; i++) { // computing next order correction to energy1 delta = coefs_check[i-1]*(scalar_prod_r(Zup, up0, VOLUME/2, 1) + scalar_prod_r(Zup, dn0, VOLUME/2, 1)); if(g_debug_level > 2 && g_proc_id == 0) printf("# NDRATCOR heatbath: c_%d*(R * Z^%d * R) = %e\n", i, i, delta); // debug for showing that the old check was giving a smaller delta if(g_debug_level > 3) { double delta_old = square_norm(up0, VOLUME/2, 1) + square_norm(dn0, VOLUME/2, 1); if(g_proc_id == 0) { printf("# NDRATCOR old check: || Z^%d * R ||^2 = %e\n", 1, delta_old); printf("# NDRATCOR new check: (c_%d*(R * Z^%d * R))^2 = %e\n", 1, 1, delta*delta); } } if(delta*delta < mnl->accprec) break; apply_Z_ndpsi(up1, dn1, up0, dn0, id, hf, &(mnl->solver_params)); assign_add_mul_r(mnl->pf, up1, coefs[i-1], VOLUME/2); assign_add_mul_r(mnl->pf2, dn1, coefs[i-1], VOLUME/2); tup = up0; tdn = dn0; up0 = up1; dn0 = dn1; up1 = tup; dn1 = tdn; } } etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called ndratcor_heatbath for id %d energy %f\n", id, mnl->energy0); } } return; }
void reweighting_factor(const int N, const int nstore) { int n = VOLUME; monomial * mnl; FILE * ofs; hamiltonian_field_t hf; hf.gaugefield = g_gauge_field; hf.momenta = NULL; hf.derivative = NULL; hf.update_gauge_copy = g_update_gauge_copy; double * data = (double*)calloc(no_monomials*N, sizeof(double)); double * trlog = (double*)calloc(no_monomials, sizeof(double)); // we compute the trlog part first, because they are independent of // stochastic noise. This is only needed for even/odd monomials for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->even_odd_flag) { init_sw_fields(); double c_sw = mnl->c_sw; if(c_sw < 0.) c_sw = 0.; sw_term( (const su3**) hf.gaugefield, mnl->kappa, c_sw); if(mnl->type != NDDETRATIO) { trlog[j] = -sw_trace(0, mnl->mu); } else { trlog[j] = -sw_trace_nd(0, mnl->mubar, mnl->epsbar); } sw_term( (const su3**) hf.gaugefield, mnl->kappa2, c_sw); if(mnl->type != NDDETRATIO) { trlog[j] -= -sw_trace(0, mnl->mu2); } else { trlog[j] -= -sw_trace_nd(0, mnl->mubar2, mnl->epsbar2); } } else { trlog[j] = 0.; } if(g_proc_id == 0 && g_debug_level > 0) { printf("# monomial[%d] %s, trlog = %e\n", j, mnl->name, trlog[j]); } } for(int i = 0; i < N; i++) { if(g_proc_id == 0 && g_debug_level > 0) { printf("# computing reweighting factors for sample %d\n", i); } for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->type != GAUGE) { if(mnl->even_odd_flag) { random_spinor_field_eo(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, n/2, 1); } else { random_spinor_field_lexic(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, n, 1); } if(g_proc_id == 0 && g_debug_level > 1) { printf("# monomial[%d] %s, energy0 = %e\n", j, mnl->name, mnl->energy0); } if(mnl->type == NDDETRATIO) { if(mnl->even_odd_flag) { random_spinor_field_eo(mnl->pf2, mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(mnl->pf, n/2, 1); } else { random_spinor_field_lexic(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(mnl->pf2, n, 1); } } } } for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->type != GAUGE) { double y = mnl->accfunction(j, &hf); data[i*no_monomials + j] = y; if(g_proc_id == 0 && g_debug_level > 0) { printf("# monomial[%d] %s, stochastic part: w_%d=%e exp(w_%d)=%e\n", j, mnl->name, j, j, y, exp(y)); } } } } if(g_proc_id == 0) { char filename[50]; sprintf(filename, "reweighting_factor.data.%.5d", nstore); if((ofs = fopen(filename, "w")) == NULL) { fatal_error("Could not open file for data output", "reweighting_factor"); } else { for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; for(int i = 0; i < N; i++) { fprintf(ofs, "%.2d %.5d %e %e %e %e %.10e\n", j, i, mnl->kappa, mnl->kappa2, mnl->mu, mnl->mu2, data[i*no_monomials + j] + trlog[j]); } } fclose(ofs); } } free(data); free(trlog); }
void rat_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; solver_pm_t solver_pm; double atime, etime, dummy; atime = gettime(); // only for non-twisted operators g_mu = 0.; g_mu3 = 0.; boundary(mnl->kappa); mnl->iter1 = 0; g_mu3 = 0.; if(mnl->type == CLOVERRAT) { g_c_sw = mnl->c_sw; init_sw_fields(); sw_term((const su3**)hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, 0.); } // we measure before the trajectory! if((mnl->rec_ev != 0) && (hf->traj_counter%mnl->rec_ev == 0)) { //if(mnl->type != CLOVERRAT) phmc_compute_ev(hf->traj_counter-1, id, &Qtm_pm_ndbipsi); //else phmc_compute_ev(hf->traj_counter-1, id, &Qsw_pm_ndbipsi); } // the Gaussian distributed random fields mnl->energy0 = 0.; random_spinor_field_eo(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, VOLUME/2, 1); // set solver parameters solver_pm.max_iter = mnl->maxiter; solver_pm.squared_solver_prec = mnl->accprec; solver_pm.no_shifts = mnl->rat.np; solver_pm.shifts = mnl->rat.nu; solver_pm.type = CGMMS; solver_pm.M_psi = mnl->Qsq; solver_pm.sdim = VOLUME/2; solver_pm.rel_prec = g_relative_precision_flag; mnl->iter0 = cg_mms_tm(g_chi_up_spinor_field, mnl->pf, &solver_pm, &dummy); assign(mnl->w_fields[2], mnl->pf, VOLUME/2); // apply C to the random field to generate pseudo-fermion fields for(int j = (mnl->rat.np-1); j > -1; j--) { // Q - i nu_j (not twisted mass term, so Qp=Qm=Q mnl->Qp(g_chi_up_spinor_field[mnl->rat.np], g_chi_up_spinor_field[j]); assign_add_mul(g_chi_up_spinor_field[mnl->rat.np], g_chi_up_spinor_field[j], -I*mnl->rat.nu[j], VOLUME/2); assign_add_mul(mnl->pf, g_chi_up_spinor_field[mnl->rat.np], I*mnl->rat.rnu[j], VOLUME/2); } etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called rat_heatbath for id %d energy %f\n", id, mnl->energy0); } } return; }