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; }
/* 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; }
void det_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.; if(mnl->even_odd_flag) { /********************************************************************* * * even/odd version * * This a term is det(\hat Q^2(\mu)) * *********************************************************************/ g_mu = mnl->mu; boundary(mnl->kappa); if(mnl->solver != CG) { fprintf(stderr, "Bicgstab currently not implemented, using CG instead! (det_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, &Qtm_pm_psi); mnl->iter1 += cg_her(g_spinor_field[DUM_DERI+1], mnl->pf, mnl->maxiter, mnl->forceprec, g_relative_precision_flag, VOLUME/2, &Qtm_pm_psi); 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 */ Qtm_minus_psi(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_tm_inv_psi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+1], EO, -1.); /* \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_tm_inv_psi(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI], EO, +1); /* \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); } else { /********************************************************************* * non even/odd version * * This term is det(Q^2 + \mu_1^2) * *********************************************************************/ g_mu = mnl->mu; boundary(mnl->kappa); if(mnl->solver == CG) { /* Invert Q_{+} Q_{-} */ /* X -> 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, &Q_pm_psi); mnl->iter1 += cg_her(g_spinor_field[DUM_DERI+1], mnl->pf, mnl->maxiter, mnl->forceprec, g_relative_precision_flag, VOLUME, &Q_pm_psi); 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 -> DUM_DERI */ Q_minus_psi(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1]); } else { /* Invert first Q_+ */ /* Y -> DUM_DERI */ chrono_guess(g_spinor_field[DUM_DERI], mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, mnl->csg_n, VOLUME/2, &Q_plus_psi); mnl->iter1 += bicgstab_complex(g_spinor_field[DUM_DERI], mnl->pf, mnl->maxiter, mnl->forceprec, g_relative_precision_flag, VOLUME, Q_plus_psi); chrono_add_solution(g_spinor_field[DUM_DERI], mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); /* Now Q_- */ /* X -> DUM_DERI+1 */ g_mu = -g_mu; chrono_guess(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI], mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, mnl->csg_n2, VOLUME/2, &Q_minus_psi); mnl->iter1 += bicgstab_complex(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI], mnl->maxiter, mnl->forceprec, g_relative_precision_flag, VOLUME, Q_minus_psi); chrono_add_solution(g_spinor_field[DUM_DERI+1], mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, &mnl->csg_n2, VOLUME/2); g_mu = -g_mu; } /* \delta Q sandwitched by Y^\dagger and X */ deriv_Sb_D_psi(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], hf); } g_mu = g_mu1; boundary(g_kappa); return; }
void ndpoly_derivative(const int id) { int j, k; monomial * mnl = &monomial_list[id]; /* This factor 2 a missing factor 2 in trace_lambda */ (*mnl).forcefactor = -2.*phmc_Cpol*phmc_invmaxev; /* Recall: The GAMMA_5 left of delta M_eo is done in deriv_Sb !!! */ if (g_epsbar!=0.0 || phmc_exact_poly==0){ /* Here comes the definitions for the chi_j fields */ /* from j=0 (chi_0 = phi) ..... to j = n-1 */ /* in g_chi_up_spinor_field[0] (g_chi_dn_spinor_field[0] we expect */ /* to find the phi field, the pseudo fermion field */ /* i.e. must be equal to mnl->pf (mnl->pf2) */ assign(g_chi_up_spinor_field[0], mnl->pf, VOLUME/2); assign(g_chi_dn_spinor_field[0], mnl->pf2, VOLUME/2); for(k = 1; k < (phmc_dop_n_cheby-1); k++) { Q_tau1_min_cconst_ND(g_chi_up_spinor_field[k], g_chi_dn_spinor_field[k], g_chi_up_spinor_field[k-1], g_chi_dn_spinor_field[k-1], phmc_root[k-1]); } /* Here comes the remaining fields chi_k ; k=n,...,2n-1 */ /*They are evaluated step-by-step overwriting the same field (phmc_dop_n_cheby)*/ assign(g_chi_up_spinor_field[phmc_dop_n_cheby], g_chi_up_spinor_field[phmc_dop_n_cheby-2], VOLUME/2); assign(g_chi_dn_spinor_field[phmc_dop_n_cheby], g_chi_dn_spinor_field[phmc_dop_n_cheby-2], VOLUME/2); for(j=(phmc_dop_n_cheby-1); j>=1; j--) { assign(g_chi_up_spinor_field[phmc_dop_n_cheby-1], g_chi_up_spinor_field[phmc_dop_n_cheby], VOLUME/2); assign(g_chi_dn_spinor_field[phmc_dop_n_cheby-1], g_chi_dn_spinor_field[phmc_dop_n_cheby], VOLUME/2); Q_tau1_min_cconst_ND(g_chi_up_spinor_field[phmc_dop_n_cheby], g_chi_dn_spinor_field[phmc_dop_n_cheby], g_chi_up_spinor_field[phmc_dop_n_cheby-1], g_chi_dn_spinor_field[phmc_dop_n_cheby-1], phmc_root[2*phmc_dop_n_cheby-3-j]); /* Get the even parts of the (j-1)th chi_spinors */ H_eo_ND(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], g_chi_up_spinor_field[j-1], g_chi_dn_spinor_field[j-1], EO); /* \delta M_eo sandwitched by chi[j-1]_e^\dagger and chi[2N-j]_o */ deriv_Sb(EO, g_spinor_field[DUM_DERI], g_chi_up_spinor_field[phmc_dop_n_cheby]); /* UP */ deriv_Sb(EO, g_spinor_field[DUM_DERI+1], g_chi_dn_spinor_field[phmc_dop_n_cheby]); /* DN */ /* Get the even parts of the (2N-j)-th chi_spinors */ H_eo_ND(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+1], g_chi_up_spinor_field[phmc_dop_n_cheby], g_chi_dn_spinor_field[phmc_dop_n_cheby], EO); /* \delta M_oe sandwitched by chi[j-1]_o^\dagger and chi[2N-j]_e */ deriv_Sb(OE, g_chi_up_spinor_field[j-1], g_spinor_field[DUM_DERI]); deriv_Sb(OE, g_chi_dn_spinor_field[j-1], g_spinor_field[DUM_DERI+1]); } } else if(g_epsbar == 0.0) { /* Here comes the definitions for the chi_j fields */ /* from j=0 (chi_0 = phi) ..... to j = n-1 */ assign(g_chi_up_spinor_field[0], mnl->pf, VOLUME/2); for(k = 1; k < (phmc_dop_n_cheby-1); k++) { Qtm_pm_min_cconst_nrm(g_chi_up_spinor_field[k], g_chi_up_spinor_field[k-1], phmc_root[k-1]); } assign(g_chi_up_spinor_field[phmc_dop_n_cheby], g_chi_up_spinor_field[phmc_dop_n_cheby-2], VOLUME/2); for(j = (phmc_dop_n_cheby-1); j >= 1; j--) { assign(g_chi_up_spinor_field[phmc_dop_n_cheby-1], g_chi_up_spinor_field[phmc_dop_n_cheby], VOLUME/2); Qtm_pm_min_cconst_nrm(g_chi_up_spinor_field[phmc_dop_n_cheby], g_chi_up_spinor_field[phmc_dop_n_cheby-1], phmc_root[2*phmc_dop_n_cheby-3-j]); Qtm_minus_psi(g_spinor_field[DUM_DERI+3],g_chi_up_spinor_field[j-1]); H_eo_tm_inv_psi(g_spinor_field[DUM_DERI+2], g_chi_up_spinor_field[phmc_dop_n_cheby], EO, -1.); deriv_Sb(OE, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+2]); H_eo_tm_inv_psi(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3], EO, 1.); deriv_Sb(EO, g_spinor_field[DUM_DERI+2], g_chi_up_spinor_field[phmc_dop_n_cheby]); Qtm_minus_psi(g_spinor_field[DUM_DERI+3],g_chi_up_spinor_field[phmc_dop_n_cheby]); H_eo_tm_inv_psi(g_spinor_field[DUM_DERI+2],g_spinor_field[DUM_DERI+3], EO, +1.); deriv_Sb(OE, g_chi_up_spinor_field[j-1] , g_spinor_field[DUM_DERI+2]); H_eo_tm_inv_psi(g_spinor_field[DUM_DERI+2], g_chi_up_spinor_field[j-1], EO, -1.); deriv_Sb(EO, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+3]); } } /* Normalisation by the largest EW is done in update_momenta using mnl->forcefactor */ }