// ----------------------------------------------------------------- // Return a_i * b_i for two complex vectors (no conjugation!) double_complex inner(complex *a, complex *b) { int i, Ndat = 16 * DIMF; double_complex dot; dot.real = a[0].real * b[0].real - a[0].imag * b[0].imag; dot.imag = a[0].imag * b[0].real + a[0].real * b[0].imag; for (i = 1; i < sites_on_node * Ndat; i++) { dot.real += a[i].real * b[i].real - a[i].imag * b[i].imag; dot.imag += a[i].imag * b[i].real + a[i].real * b[i].imag; } // Accumulate inner product across all nodes g_dcomplexsum(&dot); return dot; }
static void chem_pot_print1(double_complex pb_dMdmu_p_e, double_complex pb_dMdmu_p_o, double_complex pb_d2Mdmu2_p_e, double_complex pb_d2Mdmu2_p_o, Real mass, int jpbp_reps, int npbp_reps) { Real r_pb_dMdmu_p_e = 0.0; Real i_pb_dMdmu_p_e = 0.0; Real r_pb_dMdmu_p_o = 0.0; Real i_pb_dMdmu_p_o = 0.0; Real r_pb_d2Mdmu2_p_e = 0.0; Real i_pb_d2Mdmu2_p_e = 0.0; Real r_pb_d2Mdmu2_p_o = 0.0; Real i_pb_d2Mdmu2_p_o = 0.0; g_dcomplexsum( &pb_dMdmu_p_e ); g_dcomplexsum( &pb_dMdmu_p_o ); g_dcomplexsum( &pb_d2Mdmu2_p_e ); g_dcomplexsum( &pb_d2Mdmu2_p_o ); r_pb_dMdmu_p_e = pb_dMdmu_p_e.real*(2.0/(double)volume) ; i_pb_dMdmu_p_e = pb_dMdmu_p_e.imag*(2.0/(double)volume) ; r_pb_dMdmu_p_o = pb_dMdmu_p_o.real*(2.0/(double)volume) ; i_pb_dMdmu_p_o = pb_dMdmu_p_o.imag*(2.0/(double)volume) ; r_pb_d2Mdmu2_p_e = pb_d2Mdmu2_p_e.real*(2.0/(double)volume) ; i_pb_d2Mdmu2_p_e = pb_d2Mdmu2_p_e.imag*(2.0/(double)volume) ; r_pb_d2Mdmu2_p_o = pb_d2Mdmu2_p_o.real*(2.0/(double)volume) ; i_pb_d2Mdmu2_p_o = pb_d2Mdmu2_p_o.imag*(2.0/(double)volume) ; node0_printf("PB_DMDMU_P: mass %e %e %e %e %e ( %d of %d )\n", mass, r_pb_dMdmu_p_e, r_pb_dMdmu_p_o, i_pb_dMdmu_p_e, i_pb_dMdmu_p_o, jpbp_reps+1, npbp_reps); node0_printf("PB_D2MDMU2_P: mass %e %e %e %e %e ( %d of %d )\n", mass, r_pb_d2Mdmu2_p_e, r_pb_d2Mdmu2_p_o, i_pb_d2Mdmu2_p_e, i_pb_d2Mdmu2_p_o, jpbp_reps+1, npbp_reps); }
/* Assume the first Nvecs_curr eigenvectors have been already orthonormalized. If norm of an eigenvector is less than ORTHO_EPS, remove it. Rturn the number of new eigenvectors to be added. */ static int orthogonalize(int Nvecs, int Nvecs_curr, su3_vector **eigVec, int parity){ register int i; int j, k, Nvecs_add, n; double norm; double_complex cc; double_complex *c; j = Nvecs_curr; Nvecs_add = Nvecs; n = Nvecs_curr + Nvecs_add; c = (double_complex *)malloc(n*sizeof(double_complex)); while(j < n){ /* Modified Gram-Schmidt Orthogonality is better but more communications are needed */ for(k = 0; k < j; k++){ // c[k] = dcmplx((double)0.0,(double)0.0); // FORSOMEFIELDPARITY_OMP(i, parity, private(cc) reduction(+:c[k])){ // cc = su3_dot(eigVec[k]+i, eigVec[j]+i); // CSUM(c[k], cc); // } END_LOOP_OMP; double cctotr=0., cctoti=0.; FORSOMEFIELDPARITY_OMP(i, parity, private(cc) reduction(+:cctotr,cctoti)){ cc = su3_dot(eigVec[k]+i, eigVec[j]+i); cctotr += cc.real; cctoti += cc.imag; } END_LOOP_OMP; c[k].real = cctotr; c[k].imag = cctoti; g_dcomplexsum(c+k); FORSOMEFIELDPARITY_OMP(i, parity, default(shared)){ c_scalar_mult_sub_su3vec(eigVec[j]+i, c+k, eigVec[k]+i); } END_LOOP_OMP } /* Gram-Schmidt Less communications but poor orthogonality might happen if the number of vectors is too large. */ /* for(k = 0; k < j; k++){ c[k] = dcmplx((double)0.0,(double)0.0); FORSOMEFIELDPARITY_OMP(i, parity, private(cc) reduction(+:c[k])){ cc = su3_dot(eigVec[k]+i, eigVec[j]+i); CSUM(c[k], cc); } END_LOOP_OMP } g_vecdcomplexsum(c, j); for(k = 0; k < j; k++){ FORSOMEFIELDPARITY_OMP(i, parity, default(shared)){ c_scalar_mult_sub_su3vec(eigVec[j]+i, c+k, eigVec[k]+i); } END_LOOP_OMP } */ norm = (double)0.0; FORSOMEFIELDPARITY_OMP(i, parity, reduction(+:norm)){ norm += magsq_su3vec(eigVec[j]+i); } END_LOOP_OMP g_doublesum(&norm); norm = sqrt(norm); if( norm < ORTHO_EPS ){ Nvecs_add--; n--; for(k = j; k < n; k++){ FORSOMEFIELDPARITY_OMP(i, parity, default(shared)){ eigVec[k][i] = eigVec[k+1][i]; } END_LOOP_OMP } } else{
void f_meas_imp_field( int npbp_reps, quark_invert_control *qic, Real mass, int naik_term_epsilon_index, fermion_links_t *fl){ imp_ferm_links_t* fn = get_fm_links(fl)[naik_term_epsilon_index]; #ifdef DM_DU0 imp_ferm_links_t* fn_du0 = get_fm_du0_links(fl)[naik_term_epsilon_index]; #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) imp_ferm_links_t *fn_deps = get_fn_deps_links(fl); #endif Real r_psi_bar_psi_even, i_psi_bar_psi_even; Real r_psi_bar_psi_odd, i_psi_bar_psi_odd; Real r_ferm_action; /* local variables for accumulators */ register int i; double rfaction; double_complex pbp_e, pbp_o; complex cc; int jpbp_reps; su3_vector *gr = NULL; su3_vector *M_gr = NULL; su3_vector *M_inv_gr = NULL; #ifdef DM_DU0 double r_pb_dMdu_p_even, r_pb_dMdu_p_odd; su3_vector *dMdu_x = NULL; #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) double r_pb_dMdeps_p_even, r_pb_dMdeps_p_odd; su3_vector *dMdeps_x = NULL; #endif #ifdef CHEM_POT double_complex pb_dMdmu_p_e, pb_dMdmu_p_o; double_complex pb_d2Mdmu2_p_e, pb_d2Mdmu2_p_o; double MidM_MidM; su3_vector *dM_M_inv_gr = NULL; su3_vector *d2M_M_inv_gr = NULL; su3_vector *M_inv_dM_M_inv_gr = NULL; su3_vector *dM_M_inv_dM_M_inv_gr = NULL; #endif /* Loop over random sources */ for(jpbp_reps = 0; jpbp_reps < npbp_reps; jpbp_reps++){ rfaction = (double)0.0; pbp_e = pbp_o = dcmplx((double)0.0,(double)0.0); /* Make random source, and do inversion */ /* generate gr random; M_gr = M gr */ gr = create_v_field(); #ifndef Z2RSOURCE grsource_plain_field( gr, EVENANDODD ); #else z2rsource_plain_field( gr, EVENANDODD ); #endif /* The following operation is done in the prevailing precision. The algorithm needs to be fixed! */ M_gr = create_v_field(); ks_dirac_adj_op( gr, M_gr, mass, EVENANDODD, fn ); /* M_inv_gr = M^{-1} gr */ M_inv_gr = create_v_field(); mat_invert_uml_field( gr, M_inv_gr, qic, mass, fn ); #ifdef DM_DU0 r_pb_dMdu_p_even = r_pb_dMdu_p_odd = (double)0.0; /* dMdu_x = dM/du0 M^{-1} gr */ dMdu_x = create_v_field(); dslash_fn_field( M_inv_gr, dMdu_x, EVENANDODD, fn_du0 ); #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) r_pb_dMdeps_p_even = r_pb_dMdeps_p_odd = (double)0.0; /* dMdeps_x = dM/deps0 M^{-1} gr */ dMdeps_x = create_v_field(); dslash_fn_field( M_inv_gr, dMdeps_x, EVENANDODD, fn_deps ); #endif #ifdef CHEM_POT pb_dMdmu_p_e = pb_dMdmu_p_o = dcmplx((double)0.0,(double)0.0); pb_d2Mdmu2_p_e = pb_d2Mdmu2_p_o = dcmplx((double)0.0,(double)0.0); /* dM_M_inv_gr = dM/dmu * M_inv_gr */ /* d2M_M_inv_gr = d2M/dmu2 * M_inv_gr */ dM_M_inv_gr = create_v_field(); chem_pot_tshift(fn, dM_M_inv_gr, M_inv_gr, 3., -1.); d2M_M_inv_gr = create_v_field(); chem_pot_tshift(fn, d2M_M_inv_gr, M_inv_gr, 9., 1.); #endif /* fermion action = M_gr.M_inv_gr */ /* psi-bar-psi on even sites = gr.M_inv_gr */ FOREVENFIELDSITES(i){ rfaction += su3_rdot( M_gr+i, M_inv_gr+i ); cc = su3_dot( gr+i, M_inv_gr+i ); CSUM(pbp_e, cc); #ifdef DM_DU0 /* r_pb_dMdu_p_even = gr * dM/du0 M^{-1} gr |even*/ r_pb_dMdu_p_even += su3_rdot( gr+i, dMdu_x+i ); #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) /* r_pb_dMdu_p_even = gr * dM/du0 M^{-1} gr |even*/ r_pb_dMdeps_p_even += su3_rdot( gr+i, dMdeps_x+i ); #endif #ifdef CHEM_POT /* Compute pb_dMdmu_p, pb_d2Mdmu2_p and dM_M_inv on even sites */ cc = su3_dot( gr+i, dM_M_inv_gr+i); CSUM(pb_dMdmu_p_e, cc); cc = su3_dot( gr+i, d2M_M_inv_gr+i); CSUM(pb_d2Mdmu2_p_e, cc); #endif } /* psi-bar-psi on odd sites */ FORODDFIELDSITES(i){ cc = su3_dot( gr+i, M_inv_gr+i ); CSUM(pbp_o, cc); #ifdef DM_DU0 /* r_pb_dMdu_p_odd = gr * dM/du0 M^{-1} gr |odd*/ r_pb_dMdu_p_odd += su3_rdot( gr+i, dMdu_x+i ); #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) /* r_pb_dMdu_p_odd = gr * dM/du0 M^{-1} gr |odd*/ r_pb_dMdeps_p_odd += su3_rdot( gr+i, dMdeps_x+i ); #endif #ifdef CHEM_POT /* Compute pb_dMdmu_P, pb_d2Mdmu2_p and dM_M_inv on odd sites */ cc = su3_dot( gr+i, dM_M_inv_gr+i); CSUM(pb_dMdmu_p_o, cc); cc = su3_dot( gr+i, d2M_M_inv_gr+i); CSUM(pb_d2Mdmu2_p_o, cc); #endif } #ifdef CHEM_POT destroy_v_field(d2M_M_inv_gr); d2M_M_inv_gr = NULL; #endif destroy_v_field(M_gr); M_gr = NULL; g_dcomplexsum( &pbp_o ); g_dcomplexsum( &pbp_e ); g_doublesum( &rfaction ); #ifdef DM_DU0 destroy_v_field( dMdu_x ); dMdu_x = NULL; g_doublesum( &r_pb_dMdu_p_even ); g_doublesum( &r_pb_dMdu_p_odd ); r_pb_dMdu_p_even *= (2.0/(double)volume); r_pb_dMdu_p_odd *= (2.0/(double)volume); node0_printf("PB_DMDU_P: mass %e %e %e ( %d of %d )\n", mass, r_pb_dMdu_p_even, r_pb_dMdu_p_odd, jpbp_reps+1, npbp_reps); #endif #if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS) destroy_v_field( dMdeps_x ); dMdeps_x = NULL; g_doublesum( &r_pb_dMdeps_p_even ); g_doublesum( &r_pb_dMdeps_p_odd ); r_pb_dMdeps_p_even *= (2.0/(double)volume); r_pb_dMdeps_p_odd *= (2.0/(double)volume); node0_printf("PB_DMDEPS_P: mass %e %e %e ( %d of %d )\n", mass, r_pb_dMdeps_p_even, r_pb_dMdeps_p_odd, jpbp_reps+1, npbp_reps); #endif r_psi_bar_psi_odd = pbp_o.real*(2.0/(double)volume) ; i_psi_bar_psi_odd = pbp_o.imag*(2.0/(double)volume) ; r_psi_bar_psi_even = pbp_e.real*(2.0/(double)volume) ; i_psi_bar_psi_even = pbp_e.imag*(2.0/(double)volume) ; r_ferm_action = rfaction*(1.0/(double)volume) ; node0_printf("PBP: mass %e %e %e %e %e ( %d of %d )\n", mass, r_psi_bar_psi_even, r_psi_bar_psi_odd, i_psi_bar_psi_even, i_psi_bar_psi_odd, jpbp_reps+1, npbp_reps); node0_printf("FACTION: mass = %e, %e ( %d of %d )\n", mass, r_ferm_action, jpbp_reps+1, npbp_reps); #ifdef CHEM_POT /* Print results for pb_dMdmu_p and pb_d2Mdmu2_p */ chem_pot_print1(pb_dMdmu_p_e, pb_dMdmu_p_o, pb_d2Mdmu2_p_e, pb_d2Mdmu2_p_o, mass, jpbp_reps, npbp_reps); #endif #ifdef TR_MM_INV if(npbp_reps > 1){ su3_vector *MM_inv_gr = create_v_field(); double pbp_pbp = 0.0; mat_invert_uml_field( M_inv_gr, MM_inv_gr, qic, mass, fn ); FORALLFIELDSITES(i){ pbp_pbp += su3_rdot( gr+i, MM_inv_gr+i ); } g_doublesum( &pbp_pbp ); pbp_pbp = pbp_pbp*(1.0/(double)volume) ; node0_printf("TR_MM_INV: mass %e, %e ( %d of %d )\n", mass, pbp_pbp, jpbp_reps+1, npbp_reps); destroy_v_field(MM_inv_gr); } #endif destroy_v_field(M_inv_gr); M_inv_gr = NULL; #ifdef CHEM_POT /* M_inv_dM_M_inv_gr = M^{-1} dM_M_inv_gr */ M_inv_dM_M_inv_gr = create_v_field(); mat_invert_uml_field( dM_M_inv_gr, M_inv_dM_M_inv_gr, qic, mass, fn ); destroy_v_field(dM_M_inv_gr); dM_M_inv_gr = NULL; /* dM_M_inv_dM_M_inv_gr = dM/dmu M_inv_dM_M_inv_gr */ dM_M_inv_dM_M_inv_gr = create_v_field(); chem_pot_tshift(fn, dM_M_inv_dM_M_inv_gr, M_inv_dM_M_inv_gr, 3., -1.); destroy_v_field(M_inv_dM_M_inv_gr); M_inv_dM_M_inv_gr = NULL; /* Compute MidM_MidM */ MidM_MidM = (double)0.0; FORALLFIELDSITES(i){ MidM_MidM += su3_rdot( gr+i, dM_M_inv_dM_M_inv_gr+i); } destroy_v_field(dM_M_inv_dM_M_inv_gr); dM_M_inv_dM_M_inv_gr = NULL; chem_pot_print2(MidM_MidM, jpbp_reps, npbp_reps, mass); #endif destroy_v_field(gr); gr = NULL; } /* jpbp_reps */