static void init_gamma(void){ g1 = gamma_mat(G1); gx = gamma_mat(GX); gy = gamma_mat(GY); gz = gamma_mat(GZ); gt = gamma_mat(GT); g5 = gamma_mat(G5); }
bool Face::triangle_intersect(const Ray &r, Hit &h, Vertex *a, Vertex *b, Vertex *c, bool intersect_backfacing) const { // compute the intersection with the plane of the triangle Hit h2 = Hit(h); if (!plane_intersect(r,h2,intersect_backfacing)) return 0; // figure out the barycentric coordinates: glm::vec3 Ro = r.getOrigin(); glm::vec3 Rd = r.getDirection(); // [ ax-bx ax-cx Rdx ][ beta ] [ ax-Rox ] // [ ay-by ay-cy Rdy ][ gamma ] = [ ay-Roy ] // [ az-bz az-cz Rdz ][ t ] [ az-Roz ] // solve for beta, gamma, & t using Cramer's rule glm::mat3 detA_mat(a->get().x-b->get().x,a->get().x-c->get().x,Rd.x, a->get().y-b->get().y,a->get().y-c->get().y,Rd.y, a->get().z-b->get().z,a->get().z-c->get().z,Rd.z); float detA = glm::determinant(detA_mat); if (fabs(detA) <= 0.000001) return 0; assert (fabs(detA) >= 0.000001); glm::mat3 beta_mat(a->get().x-Ro.x,a->get().x-c->get().x,Rd.x, a->get().y-Ro.y,a->get().y-c->get().y,Rd.y, a->get().z-Ro.z,a->get().z-c->get().z,Rd.z); glm::mat3 gamma_mat(a->get().x-b->get().x,a->get().x-Ro.x,Rd.x, a->get().y-b->get().y,a->get().y-Ro.y,Rd.y, a->get().z-b->get().z,a->get().z-Ro.z,Rd.z); float beta = glm::determinant(beta_mat) / detA; float gamma = glm::determinant(gamma_mat) / detA; if (beta >= -0.00001 && beta <= 1.00001 && gamma >= -0.00001 && gamma <= 1.00001 && beta + gamma <= 1.00001) { h = h2; // interpolate the texture coordinates float alpha = 1 - beta - gamma; float t_s = alpha * a->get_s() + beta * b->get_s() + gamma * c->get_s(); float t_t = alpha * a->get_t() + beta * b->get_t() + gamma * c->get_t(); h.setTextureCoords(t_s,t_t); assert (h.getT() >= EPSILON); return 1; } return 0; }
void meson_cont_mom( complex **prop, /* prop[m][t] is where result is accumulated */ spin_wilson_vector *src1, /* quark propagator (to become antiquark) */ spin_wilson_vector *src2, /* quark propagator */ int no_q_momenta, /* no of unique mom/parity values (gt p) */ int **q_momstore, /* q_momstore[p] are the momentum components */ char **q_parity, /* q_parity[p] the parity of each mom component */ int no_gamma_corr, /* # of gamma src/snk combinations (gt g) */ int num_corr_mom[], /* number of momentum/parity values for each corr (gt k) */ int **corr_table, /* c = corr_table[g][k] correlator index */ int p_index[], /* p = p_index[c] is the momentum index */ int gout[], /* gout[c] is the sink gamma */ int gin[], /* gin[c] is the source gamma */ int meson_phase[], /* meson_phase[c] is the correlator phase */ Real meson_factor[], /* meson_factor[c] scales the correlator */ int corr_index[], /* m = corr_index[c] is the correlator index */ int r0[] /* spatial origin for defining FT phases */ ) { char myname[] = "meson_cont_mom"; int i,k,c,m,gsnk,gsrc; site *s; int sf, si; int g,p,t; int old_gamma_out; double factx = 2.0*PI/(1.0*nx) ; double facty = 2.0*PI/(1.0*ny) ; double factz = 2.0*PI/(1.0*nz) ; int px,py,pz; char ex, ey, ez; complex fourier_fact ; spin_wilson_vector localmat; /* temporary storage */ spin_wilson_vector antiquark; /* temporary storage for antiquark */ dirac_matrix *meson; dirac_matrix_v *meson_q; int *nonzero; complex tr[MAXQ]; complex tmp; complex *ftfact; gamma_matrix_t gm5, gmout, gmoutadj, gm; /* performance */ double dtime; double flops,mflops; dtime = -dclock(); flops = 0; /* Allocate temporary storage for meson propagator */ if(no_q_momenta > MAXQ) { printf("%s(%d): no_q_momenta %d exceeds max %d\n", myname, this_node, no_q_momenta,MAXQ); terminate(1); } meson = (dirac_matrix *)malloc(sites_on_node*sizeof(dirac_matrix)); if(meson == NULL){ printf("%s(%d): No room for meson\n",myname,this_node); terminate(1); } meson_q = (dirac_matrix_v *)malloc(nt*sizeof(dirac_matrix_v)); if(meson_q == NULL){ printf("%s(%d): No room for meson_q\n",myname,this_node); terminate(1); } nonzero = (int *)malloc(nt*sizeof(int)); if(nonzero == NULL){ printf("%s(%d): No room for nonzero array\n",myname,this_node); terminate(1); } for(t = 0; t < nt; t++)nonzero[t] = 0; ftfact = (complex *)malloc(no_q_momenta*sites_on_node*sizeof(complex)); if(ftfact == NULL) { printf("%s(%d): No room for FFT phases\n",myname,this_node); terminate(1); } /* ftfact contains factors such as cos(kx*x)*sin(ky*y)*exp(ikz*z) with factors of cos, sin, and exp selected according to the requested component parity */ FORALLSITES(i,s) { for(p=0; p<no_q_momenta; p++) { px = q_momstore[p][0]; py = q_momstore[p][1]; pz = q_momstore[p][2]; ex = q_parity[p][0]; ey = q_parity[p][1]; ez = q_parity[p][2]; tmp.real = 1.; tmp.imag = 0.; tmp = ff(factx*(s->x-r0[0])*px, ex, tmp); tmp = ff(facty*(s->y-r0[1])*py, ey, tmp); tmp = ff(factz*(s->z-r0[2])*pz, ez, tmp); ftfact[p+no_q_momenta*i] = tmp; } } flops += (double)sites_on_node*18*no_q_momenta; /* Run through the table of unique source-sink gamma matrix pairs and for each, do the Fourier transform according to the list of requested momenta */ /* To help suppress repetition */ old_gamma_out = -999; for(g = 0; g < no_gamma_corr; g++) { /* All gammas with the same index g must be the same */ c = corr_table[g][0]; gsrc = gin[c]; gsnk = gout[c]; /* For compatibility */ if(gsrc == GAMMAFIVE)gin[c] = G5; if(gsnk == GAMMAFIVE)gout[c] = G5; if(gsrc >= MAXGAMMA || gsnk >= MAXGAMMA) { printf("%s(%d): Illegal gamma index %d or %d\n", myname, this_node, gsrc, gsnk); terminate(1); } for(k=0; k<num_corr_mom[g]; k++) { if(gin[corr_table[g][k]] != gsrc || gout[corr_table[g][k]] != gsnk ) { printf("meson_cont_mom(%d): bad gamma list\n", this_node); terminate(1); } } /* Skip reconstruction of "meson" if "out" gamma matrix hasn't changed */ if(gsnk != old_gamma_out) { old_gamma_out = gsnk; /* Compute gm = \gamma_5 Gamma_out */ gm5 = gamma_mat(G5); gmout = gamma_mat(gsnk); gamma_adj(&gmoutadj, &gmout); mult_gamma_by_gamma(&gm5, &gmoutadj, &gm); FORALLSITES(i,s) { /* antiquark = gamma_5 adjoint of quark propagator gamma_5 */ /* But we use a complex matrix dot product below, so don't take the c.c. here and do the transpose later - so just do a gamma5 transformation now */ if( i < loopend-FETCH_UP){ prefetch_WWWW( &(src1[i].d[0]), &(src1[i].d[1]), &(src1[i].d[2]), &(src1[i].d[3])); prefetch_WWWW( &(src2[i].d[0]), &(src2[i].d[1]), &(src2[i].d[2]), &(src2[i].d[3])); } /* antiquark = \gamma_5 S_1 \gamma_5 \Gamma_out^\dagger */ mult_sw_by_gamma_l( src1+i, &localmat, G5); mult_sw_by_gamma_mat_r( &localmat, &antiquark, &gm); /* combine with src2 quark and sew together sink colors and spins to make meson Dirac matrix "meson" is then [S_2 \Gamma_out \gamma_5 S_1^\dagger \gamma_5] and is a Dirac matrix */ meson[i] = mult_swv_na( src2+i, &antiquark); } /* end FORALLSITES */ flops += (double)sites_on_node*1536; } /* end if not same Gamma_out */ /* Do FT on "meson" for momentum projection - Result in meson_q. We use a dumb FT because there are so few momenta needed. */ FORALLSITES(i,s) { for(si = 0; si < 4; si++)for(sf = 0; sf < 4; sf++) for(k=0; k<num_corr_mom[g]; k++) { c = corr_table[g][k]; p = p_index[c]; meson_q[s->t].d[si].d[sf].e[p].real = 0.; meson_q[s->t].d[si].d[sf].e[p].imag = 0; } } FORALLSITES(i,s) { nonzero[s->t] = 1; /* To save steps below */ for(si = 0; si < 4; si++) for(sf = 0; sf < 4; sf++) { for(k=0; k<num_corr_mom[g]; k++) { c = corr_table[g][k]; p = p_index[c]; fourier_fact = ftfact[p+no_q_momenta*i]; meson_q[s->t].d[si].d[sf].e[p].real += meson[i].d[si].d[sf].real*fourier_fact.real - meson[i].d[si].d[sf].imag*fourier_fact.imag; meson_q[s->t].d[si].d[sf].e[p].imag += meson[i].d[si].d[sf].real*fourier_fact.imag + meson[i].d[si].d[sf].imag*fourier_fact.real; } } }
static double dirac_v_tr_gamma(complex *tr, dirac_matrix_v *src, int gamma, int phase[], Real factor[], int ct[], int nc, int p_index[]) { int s2,s; /* spin indices */ int k, c, p, ph; complex z = {0.,0.}; Real fact; double flops = 0; /* One value for each momentum */ for(k=0; k<nc; k++) tr[k].real = tr[k].imag = 0; /* For each momentum in list, multiply by gamma and take trace */ for(s=0;s<4;s++){ s2 = gamma_mat(gamma).row[s].column; switch (gamma_mat(gamma).row[s].phase){ case 0: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; z = src->d[s2].d[s].e[p]; CSUM(tr[k],z); } break; case 1: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESPLUSI( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } break; case 2: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESMINUSONE( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } break; case 3: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESMINUSI( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } } } /* Normalization and phase */ for(k=0; k<nc; k++){ c = ct[k]; ph = phase[c]; fact = factor[c]; switch(ph){ case 0: z = tr[k]; break; case 1: TIMESPLUSI( tr[k], z); break; case 2: TIMESMINUSONE( tr[k], z); break; case 3: TIMESMINUSI( tr[k], z); } CMULREAL(z,fact,tr[k]); } flops = 4*nc; return flops; } /* dirac_v_tr_gamma */