void grsource_w() { register int i,j,k; register site *s; FORMYSITES(i,s){ for(k=0;k<4;k++)for(j=0;j<3;j++){ #ifdef SITERAND s->g_rand.d[k].c[j].real = gaussian_rand_no(&(s->site_prn)); s->g_rand.d[k].c[j].imag = gaussian_rand_no(&(s->site_prn)); #else s->g_rand.d[k].c[j].real = gaussian_rand_no(&node_prn); s->g_rand.d[k].c[j].imag = gaussian_rand_no(&node_prn); #endif s->psi.d[k].c[j] = cmplx(0.0,0.0); } } #ifdef LU /* use g_rand on odd sites as temporary storage: g_rand(odd) = Dslash^adjoint * g_rand(even) */ dslash_w_site( F_OFFSET(g_rand), F_OFFSET(g_rand), MINUS, ODD); dslash_w_site( F_OFFSET(g_rand), F_OFFSET(chi) , MINUS, EVEN); FOREVENSITES(i,s){ scalar_mult_add_wvec( &(s->g_rand), &(s->chi), -kappa*kappa, &(s->chi) ); }
// residues, roots and order define rational function approximation for // x^(nf/8) void grsource_imp_rhmc( field_offset dest, params_ratfunc *rf, int parity, su3_vector **multi_x, su3_vector *sumvec, Real my_rsqmin, int my_niter, int my_prec, ferm_links_t *fn) { register int i,j; register site *s; Real final_rsq; int order = rf->order; Real *residues = rf->res; Real *roots = rf->pole; /*TEMP*/ double sum; sum=0.0; FORSOMEPARITY(i,s,parity){ for(j=0;j<3;j++){ #ifdef SITERAND s->g_rand.c[j].real = gaussian_rand_no(&(s->site_prn)); s->g_rand.c[j].imag = gaussian_rand_no(&(s->site_prn)); #else s->g_rand.c[j].real = gaussian_rand_no(&node_prn); s->g_rand.c[j].imag = gaussian_rand_no(&node_prn); #endif } /*TEMP*/ sum += (double)magsq_su3vec( &(s->g_rand) ); } /*TEMP*/g_doublesum( &sum); node0_printf("GRSOURCE: sum = %.10e\n",sum); ks_ratinv( F_OFFSET(g_rand), multi_x, roots, order, my_niter, my_rsqmin, my_prec, parity, &final_rsq, fn ); ks_rateval( sumvec, F_OFFSET(g_rand), multi_x, residues, order, parity ); FORSOMEPARITY(i,s,parity){ *(su3_vector *)F_PT(s,dest) = sumvec[i]; }
void grsource_imp_u1( field_offset dest, Real mass, int parity, ferm_links_u1_t *fn ) { register int i; register site *s; FORALLMYSITES(i,s){ #ifdef SITERAND s->g_rand.real = gaussian_rand_no(&(s->site_prn)); s->g_rand.imag = gaussian_rand_no(&(s->site_prn)); #else s->g_rand.real = gaussian_rand_no(&node_prn); s->g_rand.imag = gaussian_rand_no(&node_prn); #endif }
// Return the number of iterations from the inversion int grsource(vector *src) { #if (DIMF != 4) #error "Assuming DIMF=4!" #endif register int i, j; register site *s; int avs_iters; Real size_r; vector **psim = malloc(Norder * sizeof(**psim)); // Allocate psim (will be zeroed in congrad_multi) for (i = 0; i < Norder; i++) psim[i] = malloc(sites_on_node * sizeof(vector)); // Begin with pure gaussian random numbers FORALLSITES(i, s) { #ifdef SITERAND src[i].c[0] = gaussian_rand_no(&(s->site_prn)); src[i].c[1] = gaussian_rand_no(&(s->site_prn)); src[i].c[2] = gaussian_rand_no(&(s->site_prn)); src[i].c[3] = gaussian_rand_no(&(s->site_prn)); #else src[i].c[0] = gaussian_rand_no(&node_prn); src[i].c[1] = gaussian_rand_no(&node_prn); src[i].c[2] = gaussian_rand_no(&node_prn); src[i].c[3] = gaussian_rand_no(&node_prn); #endif }
// ----------------------------------------------------------------- // For single pseudofermion or inner Hasenbusch pseudofermion // dest = M^dag g_rand void grsource_imp(field_offset dest, Real M, int parity) { register int i, j; register site *s; FORALLSITES(i, s) { for (j = 0; j < 3; j++) { #ifdef SITERAND s->g_rand.c[j].real = gaussian_rand_no(&(s->site_prn)); s->g_rand.c[j].imag = gaussian_rand_no(&(s->site_prn)); #else s->g_rand.c[j].real = gaussian_rand_no(&node_prn); s->g_rand.c[j].imag = gaussian_rand_no(&node_prn); #endif } } // Hit g_rand with M^dag dslash(F_OFFSET(g_rand), dest, parity); scalar_mult_latvec(dest, -1.0, dest, parity); scalar_mult_add_latvec(dest, F_OFFSET(g_rand), 2.0 * M, dest, parity); }
/* "parity" is EVEN, ODD, or EVENANDODD. The parity is the parity at which phi is computed. g_rand must always be computed at all sites. */ void grsource(int parity) { register int i,j; register site *s; FORALLSITES(i,s){ #ifdef SCHROED_FUN if(s->t > 0){ #endif for(j=0;j<3;j++){ #ifdef SITERAND s->g_rand.c[j].real = gaussian_rand_no(&(s->site_prn)); s->g_rand.c[j].imag = gaussian_rand_no(&(s->site_prn)); #else s->g_rand.c[j].real = gaussian_rand_no(&node_prn); s->g_rand.c[j].imag = gaussian_rand_no(&node_prn); #endif } #ifdef SCHROED_FUN } else{ /* Set all fermion vectors to zero at t=0 */ for(j=0;j<3;j++){ s->phi.c[j].real = s->phi.c[j].imag = 0.0; s->resid.c[j].real = s->resid.c[j].imag = 0.0; s->cg_p.c[j].real = s->cg_p.c[j].imag = 0.0; s->xxx.c[j].real = s->xxx.c[j].imag = 0.0; s->ttt.c[j].real = s->ttt.c[j].imag = 0.0; s->g_rand.c[j].real = s->g_rand.c[j].imag = 0.0; } } #endif } clear_latvec( F_OFFSET(xxx), EVENANDODD ); dslash( F_OFFSET(g_rand), F_OFFSET(phi), parity); scalar_mult_latvec( F_OFFSET(phi), -1.0, F_OFFSET(phi), parity ); scalar_mult_add_latvec( F_OFFSET(phi), F_OFFSET(g_rand), 2.0*mass, F_OFFSET(phi), parity ); }/* grsource */
void random_anti_hermitian( anti_hermitmat *mat_antihermit, double_prn *prn_pt) { Real r3,r8; Real sqrt_third; sqrt_third = sqrt( (double)(1.0/3.0) ); r3=gaussian_rand_no(prn_pt); r8=gaussian_rand_no(prn_pt); mat_antihermit->m00im=r3+sqrt_third*r8; mat_antihermit->m11im= -r3+sqrt_third*r8; mat_antihermit->m22im= -2.0*sqrt_third*r8; mat_antihermit->m01.real=gaussian_rand_no(prn_pt); mat_antihermit->m02.real=gaussian_rand_no(prn_pt); mat_antihermit->m12.real=gaussian_rand_no(prn_pt); mat_antihermit->m01.imag=gaussian_rand_no(prn_pt); mat_antihermit->m02.imag=gaussian_rand_no(prn_pt); mat_antihermit->m12.imag=gaussian_rand_no(prn_pt); }/*random_anti_hermitian_*/
// ----------------------------------------------------------------- // Gaussian random vector void rand_src(vector *src) { #if (DIMF != 4) #error "Assuming DIMF=4!" #endif register int i; register site *s; // Begin with pure gaussian random numbers FORALLSITES(i, s) { #ifdef SITERAND src[i].c[0] = gaussian_rand_no(&(s->site_prn)); src[i].c[1] = gaussian_rand_no(&(s->site_prn)); src[i].c[2] = gaussian_rand_no(&(s->site_prn)); src[i].c[3] = gaussian_rand_no(&(s->site_prn)); #else src[i].c[0] = gaussian_rand_no(&node_prn); src[i].c[1] = gaussian_rand_no(&node_prn); src[i].c[2] = gaussian_rand_no(&node_prn); src[i].c[3] = gaussian_rand_no(&node_prn); #endif }
// ----------------------------------------------------------------- // Gaussian random Twist_Fermion void rand_TFsource(Twist_Fermion *src) { register int i, j, mu; register site *s; complex grn; // Begin with pure gaussian random numbers FORALLSITES(i, s) { clear_TF(&(src[i])); for (j = 0; j < DIMF; j++) { // Site fermions #ifdef SITERAND grn.real = gaussian_rand_no(&(s->site_prn)); grn.imag = gaussian_rand_no(&(s->site_prn)); #else grn.real = gaussian_rand_no(&node_prn); grn.imag = gaussian_rand_no(&node_prn); #endif c_scalar_mult_sum_mat(&(Lambda[j]), &grn, &(src[i].Fsite)); FORALLDIR(mu) { // Link fermions #ifdef SITERAND grn.real = gaussian_rand_no(&(s->site_prn)); grn.imag = gaussian_rand_no(&(s->site_prn)); #else grn.real = gaussian_rand_no(&node_prn); grn.imag = gaussian_rand_no(&node_prn); #endif c_scalar_mult_sum_mat(&(Lambda[j]), &grn, &(src[i].Flink[mu])); } for (mu = 0; mu < NPLAQ; mu++) { // Plaquette fermions #ifdef SITERAND grn.real = gaussian_rand_no(&(s->site_prn)); grn.imag = gaussian_rand_no(&(s->site_prn)); #else grn.real = gaussian_rand_no(&node_prn); grn.imag = gaussian_rand_no(&node_prn); #endif c_scalar_mult_sum_mat(&(Lambda[j]), &grn, &(src[i].Fplaq[mu])); } } }
void random_gauge_trans(Twist_Fermion *TF) { int a, b, i, j, x = 1, t = 1, s = node_index(x, t); complex tc; matrix Gmat, tmat, etamat, psimat[NUMLINK], chimat; if (this_node != 0) { printf("random_gauge_trans: only implemented in serial so far\n"); fflush(stdout); terminate(1); } if (nx < 4 || nt < 4) { printf("random_gauge_trans: doesn't deal with boundaries, "); printf("needs to be run on larger volume\n"); fflush(stdout); terminate(1); } // Set up random gaussian matrix, then unitarize it clear_mat(&tmat); for (j = 0; j < DIMF; j++) { #ifdef SITERAND tc.real = gaussian_rand_no(&(lattice[0].site_prn)); tc.imag = gaussian_rand_no(&(lattice[0].site_prn)); #else tc.real = gaussian_rand_no(&(lattice[0].node_prn)); tc.imag = gaussian_rand_no(&(lattice[0].node_prn)); #endif c_scalar_mult_sum_mat(&(Lambda[j]), &tc, &tmat); } polar(&tmat, &Gmat); // Confirm unitarity or check invariance when Gmat = I // mult_na(&Gmat, &Gmat, &tmat); // dumpmat(&tmat); // mat_copy(&tmat, &Gmat); // Left side of local eta clear_mat(&etamat); // Construct G eta = sum_j eta^j G Lambda^j for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Fsite.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &etamat); } // Project out eta^j = -Tr[Lambda^j G eta] for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &etamat, &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fsite.c[j]); } // Right side of local eta clear_mat(&etamat); // Construct eta Gdag = sum_j eta^j Lambda^j Gdag for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Fsite.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &etamat); } // Project out eta^j = -Tr[eta Gdag Lambda^j] for (j = 0; j < DIMF; j++) { mult_nn(&etamat, &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fsite.c[j]); } // Left side of local links and psis; right side of local chis FORALLDIR(a) { mult_nn(&Gmat, &(lattice[s].link[a]), &tmat); mat_copy(&tmat, &(lattice[s].link[a])); clear_mat(&(psimat[a])); for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Flink[a].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[a])); } for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &(psimat[a]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[a].c[j]); } for (b = a + 1; b < NUMLINK; b++) { clear_mat(&(chimat)); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Fplaq.c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(chimat)); } for (j = 0; j < DIMF; j++) { mult_nn(&(chimat), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fplaq[i].c[j]); } } } // Right side of neighboring links and psis // TODO: Presumably we can convert this to a loop... s = node_index(x - 1, t); mult_na(&(lattice[s].link[0]), &Gmat, &tmat); mat_copy(&tmat, &(lattice[s].link[0])); clear_mat(&(psimat[0])); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Flink[0].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[0])); } for (j = 0; j < DIMF; j++) { mult_nn(&(psimat[0]), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[0].c[j]); } s = node_index(x, t - 1); mult_na(&(lattice[s].link[3]), &Gmat, &tmat); mat_copy(&tmat, &(lattice[s].link[3])); clear_mat(&(psimat[3])); for (j = 0; j < DIMF; j++) { mult_na(&(Lambda[j]), &Gmat, &tmat); tc = TF[s].Flink[3].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(psimat[3])); } for (j = 0; j < DIMF; j++) { mult_nn(&(psimat[3]), &(Lambda[j]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Flink[3].c[j]); } // Left side of neighboring chi s = node_index(x - 1, t - 1); i = plaq_index[0][3]; clear_mat(&(chimat[i])); for (j = 0; j < DIMF; j++) { mult_nn(&Gmat, &(Lambda[j]), &tmat); tc = TF[s].Fplaq[i].c[j]; c_scalar_mult_sum_mat(&tmat, &tc, &(chimat[i])); } for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[j]), &(chimat[i]), &tmat); tc = trace(&tmat); CNEGATE(tc, TF[s].Fplaq[i].c[j]); } }
// ----------------------------------------------------------------- void ranmom() { #if (DIMF != 4) #error "Assuming DIMF=4!" #endif register int i; register site *s; FORALLSITES(i, s) { #ifdef SITERAND mom[i].e[0] = gaussian_rand_no(&(s->site_prn)); mom[i].e[1] = gaussian_rand_no(&(s->site_prn)); mom[i].e[2] = gaussian_rand_no(&(s->site_prn)); mom[i].e[3] = gaussian_rand_no(&(s->site_prn)); mom[i].e[4] = gaussian_rand_no(&(s->site_prn)); mom[i].e[5] = gaussian_rand_no(&(s->site_prn)); #else mom[i].e[0] = gaussian_rand_no(&(s->node_prn)); mom[i].e[1] = gaussian_rand_no(&(s->node_prn)); mom[i].e[2] = gaussian_rand_no(&(s->node_prn)); mom[i].e[3] = gaussian_rand_no(&(s->node_prn)); mom[i].e[4] = gaussian_rand_no(&(s->node_prn)); mom[i].e[5] = gaussian_rand_no(&(s->node_prn)); #endif }