void RotateBasis_qdp(QDP_ColorVector **eigVec, Matrix *V, QDP_Subset subset) { QLA_Complex z; QDP_ColorVector **Tmp; int i, j, N; N = V->N; /* Allocate the temporary vectors needed */ Tmp = malloc(N*sizeof(QDP_ColorVector *)); for(i=0; i<N; i++) Tmp[i] = QDP_create_V(); for(i=0; i<N; i++) { QDP_V_eq_zero(Tmp[i], subset); for(j=0; j<N; j++) { QLA_real(z) = V->M[j][i].real; QLA_imag(z) = V->M[j][i].imag; QDP_V_peq_c_times_V(Tmp[i], &z, eigVec[j], subset); } } /* Copy rotated basis to the eigVec and free temporaries */ for(i=0; i<N; i++) { QDP_V_eq_V(eigVec[i], Tmp[i], subset); normalize_qdp(eigVec[i], subset); QDP_destroy_V(Tmp[i]); } free(Tmp); }
void asqtadInvert(QOP_info_t *info, QOP_FermionLinksAsqtad *fla, QOP_invert_arg_t *invarg, QOP_resid_arg_t *residarg[], QLA_Real *masses, int nm, QDP_ColorVector *prop[], QDP_ColorVector *source) { #define NC QDP_get_nc(source) QDP_Subset sub=QDP_all; if(invarg->evenodd==QOP_EVEN) { sub = QDP_even; } else if(invarg->evenodd==QOP_ODD) { sub = QDP_odd; } QOP_F_FermionLinksAsqtad *ffla = QOP_FD_asqtad_create_L_from_L(fla); QLA_F_Real m[nm]; QDP_F_ColorVector *x[nm], *b; for(int i=0; i<nm; i++) { m[i] = masses[i]; x[i] = QDP_F_create_V(); QDP_F_V_eq_zero(x[i], sub); residarg[i]->final_iter = 0; residarg[i]->final_restart = 0; } b = QDP_F_create_V(); QDP_FD_V_eq_V(b, source, sub); double flops=0, secs=0; int its=0; double preres = 1e-4; if(nm>1) { QOP_resid_arg_t **ra = residarg; QLA_F_Real *mp = m; QDP_F_ColorVector **xp = x; switch(QOP_Nc) { #ifdef HAVE_NC1 case 1: QOP_F1_asqtad_invert_multi_qdp(info, (QOP_F1_FermionLinksAsqtad*)ffla, invarg, &ra, &mp, &nm, (QDP_F1_ColorVector***)&xp, (QDP_F1_ColorVector**)&b, 1); break; #endif #ifdef HAVE_NC2 case 2: QOP_F2_asqtad_invert_multi_qdp(info, (QOP_F2_FermionLinksAsqtad*)ffla, invarg, &ra, &mp, &nm, (QDP_F2_ColorVector***)&xp, (QDP_F2_ColorVector**)&b, 1); break; #endif #ifdef HAVE_NC3 case 3: QOP_F3_asqtad_invert_multi_qdp(info, (QOP_F3_FermionLinksAsqtad*)ffla, invarg, &ra, &mp, &nm, (QDP_F3_ColorVector***)&xp, (QDP_F3_ColorVector**)&b, 1); break; #endif default: QOP_F_asqtad_invert_multi_qdp(info, ffla, invarg, &ra, &mp, &nm, &xp, &b, 1); } for(int i=0; i<nm; i++) { QDP_DF_V_eq_V(prop[i], x[i], sub); } its += residarg[0]->final_iter; secs += info->final_sec; flops += info->final_flop; } QLA_Real norm2in; QDP_r_eq_norm2_V(&norm2in, source, sub); QDP_ColorVector *Dprop, *r; r = QDP_create_V(); Dprop = QDP_create_V(); for(int i=0; i<nm; i++) { QLA_Real rsq, rsqmin; int iters=0, restarts=0; QOP_resid_arg_t res_arg = *residarg[i]; QLA_Real rsqstop = res_arg.rsqmin*norm2in; while(1) { get_resid(r, prop[i], source, fla, masses[i], invarg->evenodd, Dprop); QDP_r_eq_norm2_V(&rsq, r, sub); //printf0("its: %i resid[%i]/in = %g\n", its, i, sqrt(rsq/norm2in)); if(rsq<rsqstop) break; if(restarts>invarg->max_restarts) break; if(iters>0) restarts++; rsqmin = preres*preres; if(rsqstop/rsq>rsqmin) rsqmin = rsqstop/rsq; rsqmin *= 0.99; res_arg.rsqmin = rsqmin; if(1) { QDP_FD_V_eq_V(b, r, sub); QDP_F_V_eq_zero(x[i], sub); switch(QOP_Nc) { #ifdef HAVE_NC1 case 1: QOP_F1_asqtad_invert_qdp(info, (QOP_F1_FermionLinksAsqtad*)ffla, invarg, &res_arg, m[i], (QDP_F1_ColorVector*)x[i], (QDP_F1_ColorVector*)b); break; #endif #ifdef HAVE_NC2 case 2: QOP_F2_asqtad_invert_qdp(info, (QOP_F2_FermionLinksAsqtad*)ffla, invarg, &res_arg, m[i], (QDP_F2_ColorVector*)x[i], (QDP_F2_ColorVector*)b); break; #endif #ifdef HAVE_NC3 case 3: QOP_F3_asqtad_invert_qdp(info, (QOP_F3_FermionLinksAsqtad*)ffla, invarg, &res_arg, m[i], (QDP_F3_ColorVector*)x[i], (QDP_F3_ColorVector*)b); break; #endif default: QOP_F_asqtad_invert_qdp(info, ffla, invarg, &res_arg, m[i], x[i], b); } QDP_DF_V_eq_V(Dprop, x[i], sub); } else { QDP_V_eq_zero(Dprop, sub); QOP_asqtad_invert_qdp(info, fla, invarg, &res_arg, masses[i], Dprop, r); } residarg[i]->final_restart++; residarg[i]->final_iter += res_arg.final_iter; its += res_arg.final_iter; iters += res_arg.final_iter; secs += info->final_sec; flops += info->final_flop; QDP_V_peq_V(prop[i], Dprop, sub); } //printf0("iters = %4i secs = %8f mflops = %.0f resid = %g\n", its, //secs, 1e-6*flops/secs, sqrt(rsq/norm2in)); } info->final_sec = secs; info->final_flop = flops; QDP_destroy_V(r); QDP_destroy_V(Dprop); QDP_F_destroy_V(b); for(int i=0; i<nm; i++) { QDP_F_destroy_V(x[i]); } QOP_F_asqtad_destroy_L(ffla); #undef NC }