void d_plaquette(double *ss_plaq,double *st_plaq) { register int i,dir1,dir2; register site *s; register su3_matrix *m1,*m4; double ss_sum,st_sum; msg_tag *mtag0,*mtag1; ss_sum = st_sum = 0.0; for(dir1=YUP;dir1<=TUP;dir1++){ for(dir2=XUP;dir2<dir1;dir2++){ mtag0 = start_gather_site( F_OFFSET(link[dir2]), sizeof(su3_matrix), dir1, EVENANDODD, gen_pt[0] ); mtag1 = start_gather_site( F_OFFSET(link[dir1]), sizeof(su3_matrix), dir2, EVENANDODD, gen_pt[1] ); FORALLSITES(i,s){ m1 = &(s->link[dir1]); m4 = &(s->link[dir2]); mult_su3_an(m4,m1,&(s->tempmat1)); } wait_gather(mtag0); FORALLSITES(i,s){ #ifdef SCHROED_FUN if(dir1==TUP ){ if(s->t==(nt-1)){ mult_su3_nn( &(s->tempmat1), &(s->boundary[dir2]), &(s->staple)); } else{ mult_su3_nn( &(s->tempmat1), (su3_matrix *)(gen_pt[0][i]), &(s->staple)); } } else if(s->t > 0){ mult_su3_nn( &(s->tempmat1), (su3_matrix *)(gen_pt[0][i]), &(s->staple)); } #else mult_su3_nn( &(s->tempmat1),(su3_matrix *)(gen_pt[0][i]), &(s->staple) ); #endif } wait_gather(mtag1); FORALLSITES(i,s){ if(dir1==TUP )st_sum += (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&(s->staple) ); #ifdef SCHROED_FUN else if(s->t > 0) ss_sum += (double) #else else ss_sum += (double) #endif realtrace_su3((su3_matrix *)(gen_pt[1][i]),&(s->staple) ); } cleanup_gather(mtag0); cleanup_gather(mtag1); } }
/* Computes the field strength components and topological charge */ void fmunu_fmunu( double *time, double *space, double *charge ) { /* Site variables */ register int i; register site *s; /* Temporary component storage */ su3_matrix *ft, *fs; /* Initialize sums */ *time = *space = *charge = 0; /* Compute 8*F_mu,nu at each site */ make_field_strength( F_OFFSET(link), F_OFFSET(fieldstrength) ); /* Loop over each site to sum F_mu,nu components */ FORALLSITES(i, s) { fs = &(s->fieldstrength[FS_XY]); ft = &(s->fieldstrength[FS_ZT]); *time -= real_trace_nn(ft, ft); *space -= real_trace_nn(fs, fs); *charge -= real_trace_nn(fs, ft); fs = &(s->fieldstrength[FS_XZ]); ft = &(s->fieldstrength[FS_YT]); *time -= real_trace_nn(ft, ft); *space -= real_trace_nn(fs, fs); *charge -= realtrace_su3(fs, ft); /* ReTr{ fs.dag * ft } */ fs = &(s->fieldstrength[FS_YZ]); ft = &(s->fieldstrength[FS_XT]); *time -= real_trace_nn(ft, ft); *space -= real_trace_nn(fs, fs); *charge -= real_trace_nn(fs, ft); }
void d_plaquette_minmax(double *ss_plaq,double *st_plaq, double *ss_plaq_min, double *st_plaq_min, double *ss_plaq_max, double *st_plaq_max) { /* su3mat is scratch space of size su3_matrix */ su3_matrix *su3mat; register int i,dir1,dir2; register site *s; register int first_pass_s,first_pass_t; register su3_matrix *m1,*m4; su3_matrix mtmp; double ss_sum,st_sum; double rtrace_s, rtrace_t, ss_min, st_min, ss_max, st_max; msg_tag *mtag0,*mtag1; ss_sum = st_sum = 0.0; first_pass_s=1; first_pass_t=1; su3mat = (su3_matrix *)malloc(sizeof(su3_matrix)*sites_on_node); if(su3mat == NULL) { printf("plaquette: can't malloc su3mat\n"); fflush(stdout); terminate(1); } for(dir1=YUP;dir1<=TUP;dir1++){ for(dir2=XUP;dir2<dir1;dir2++){ mtag0 = start_gather_site( F_OFFSET(link[dir2]), sizeof(su3_matrix), dir1, EVENANDODD, gen_pt[0] ); mtag1 = start_gather_site( F_OFFSET(link[dir1]), sizeof(su3_matrix), dir2, EVENANDODD, gen_pt[1] ); FORALLSITES(i,s){ m1 = &(s->link[dir1]); m4 = &(s->link[dir2]); mult_su3_an(m4,m1,&su3mat[i]); } wait_gather(mtag0); wait_gather(mtag1); FORALLSITES(i,s){ #ifdef SCHROED_FUN if(dir1==TUP ){ if(s->t==(nt-1)){ mult_su3_nn( &su3mat[i], &(s->boundary[dir2]), &mtmp); } else{ mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); } rtrace_t = realtrace_su3((su3_matrix *)(gen_pt[1][i]), &mtmp); st_sum += rtrace_t; } else if(s->t > 0){ mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); rtrace_s = realtrace_su3((su3_matrix *)(gen_pt[1][i]), &mtmp); ss_sum += rtrace_s; } #else mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); if(dir1==TUP ) { rtrace_t = (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); st_sum += rtrace_t; } else { rtrace_s = (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); ss_sum += rtrace_s; } #endif // printf("Plaq i=%d, dir1=%d, dir2=%d: %f %f\n", // i,dir1,dir2,rtrace_s,rtrace_t); /* set min and max values on the first pass */ if( dir1==TUP ) { if( 1==first_pass_t ) { st_min = rtrace_t; st_max = rtrace_t; first_pass_t = 0; } else { if( rtrace_t < st_min ) st_min = rtrace_t; if( rtrace_t > st_max ) st_max = rtrace_t; } } else { if( 1==first_pass_s ) { ss_min = rtrace_s; ss_max = rtrace_s; first_pass_s = 0; } else { if( rtrace_s < ss_min ) ss_min = rtrace_s; if( rtrace_s > ss_max ) ss_max = rtrace_s; } } } cleanup_gather(mtag0); cleanup_gather(mtag1); } }
/* update the momenta with the gauge force */ void QOP_symanzik_1loop_gauge_force(QOP_info_t *info, QOP_GaugeField *gauge, QOP_Force *force, QOP_gauge_coeffs_t *coeffs, Real eps) { register int i,dir; register site *st; su3_matrix tmat1; register Real eb3; /* Note: eps now includes eps*beta */ register su3_matrix* momentum; su3_matrix *staple, *tempmat1; /* lengths of various kinds of loops */ int *loop_length = get_loop_length(); /* number of rotations/reflections for each kind */ int *loop_num = get_loop_num(); /* table of directions, 1 for each kind of loop */ int ***loop_table = get_loop_table(); /* table of coefficients in action, for various "representations" (actually, powers of the trace) */ Real **loop_coeff = get_loop_coeff(); /* We make our own */ int max_length = get_max_length(); /* For Symanzik 1 loop! */ int nloop = get_nloop(); int nreps = get_nreps(); su3_matrix *forwardlink[4]; su3_matrix *tmpmom[4]; int nflop = 153004; /* For Symanzik1 action */ Real final_flop; double dtime; int j,k; int *dirs,length; int *path_dir,path_length; int ln,iloop; Real action,act2,new_term; int ncount; char myname[] = "imp_gauge_force"; dtime=-dclock(); info->status = QOP_FAIL; /* Parity requirements */ if(gauge->evenodd != QOP_EVENODD || force->evenodd != QOP_EVENODD ) { printf("QOP_asqtad_force: Bad parity gauge %d force %d\n", gauge->evenodd, force->evenodd); return; } /* Map field pointers to local static pointers */ FORALLUPDIR(dir){ forwardlink[dir] = gauge->g + dir*sites_on_node; tmpmom[dir] = force->f + dir*sites_on_node; } /* Check loop coefficients */ if(coeffs->plaquette != loop_coeff[0][0] || coeffs->rectangle != loop_coeff[1][0] || coeffs->parallelogram != loop_coeff[2][0]) { printf("%s(%d): Path coeffs don't match\n",myname,this_node); return; } /* Allocate arrays according to action */ dirs = (int *)malloc(max_length*sizeof(int)); if(dirs == NULL){ printf("%s(%d): Can't malloc dirs\n",myname,this_node); return; } path_dir = (int *)malloc(max_length*sizeof(int)); if(path_dir == NULL){ printf("%s(%d): Can't malloc path_dir\n",myname,this_node); return; } staple = (su3_matrix *)special_alloc(sites_on_node*sizeof(su3_matrix)); if(staple == NULL){ printf("%s(%d): Can't malloc temporary\n",myname,this_node); return; } tempmat1 = (su3_matrix *)special_alloc(sites_on_node*sizeof(su3_matrix)); if(tempmat1 == NULL){ printf("%s(%d): Can't malloc temporary\n",myname,this_node); return; } eb3 = eps/3.0; /* Loop over directions, update mom[dir] */ for(dir=XUP; dir<=TUP; dir++){ FORALLSITES(i,st)for(j=0;j<3;j++)for(k=0;k<3;k++){ staple[i].e[j][k]=cmplx(0.0,0.0); } END_LOOP ncount=0; for(iloop=0;iloop<nloop;iloop++){ length=loop_length[iloop]; for(ln=0;ln<loop_num[iloop];ln++){ /**printf("UPD: "); printpath( loop_table[iloop][ln], length );**/ /* set up dirs. we are looking at loop starting in "XUP" direction, rotate so it starts in "dir" direction. */ for(k=0;k<length;k++){ if( GOES_FORWARDS(loop_table[iloop][ln][k]) ){ dirs[k]=(dir+loop_table[iloop][ln][k] )% 4; } else { dirs[k]=OPP_DIR( (dir+OPP_DIR(loop_table[iloop][ln][k]))%4 ); } } path_length= length-1; /* generalized "staple" */ /* check for links in direction of momentum to be updated, each such link gives a contribution. Note the direction of the path - opposite the link. */ for(k=0;k<length;k++)if( dirs[k]==dir||dirs[k]==OPP_DIR(dir)) { if( GOES_FORWARDS(dirs[k]) ) for(j=0;j<path_length;j++) { path_dir[j] = dirs[(k+j+1)%length]; } if( GOES_BACKWARDS(dirs[k]) ) for(j=0;j<path_length;j++) { path_dir[path_length-1-j] = OPP_DIR(dirs[(k+j+1)%length]); } /**if(dir==XUP)printf("X_UPDATE PATH: "); printpath( path_dir, path_length );**/ path_product(path_dir,path_length, tempmat1); /* We took the path in the other direction from our old convention in order to get it to end up "at our site", so now take adjoint */ /* then compute "single_action" contribution to staple */ FORALLSITES(i,st){ su3_adjoint( &(tempmat1[i]), &tmat1 ); /* first we compute the fundamental term */ new_term = loop_coeff[iloop][0]; /* now we add in the higher representations */ if(nreps > 1){ node0_printf("WARNING: THIS CODE IS NOT TESTED\n"); exit(0); act2=1.0; action = 3.0 - realtrace_su3(forwardlink[dir]+i, &tmat1 ); for(j=1;j<nreps;j++){ act2 *= action; new_term += loop_coeff[iloop][j]*act2*(Real)(j+1); } } /* end if nreps > 1 */ scalar_mult_add_su3_matrix( &(staple[i]), &tmat1, new_term, &(staple[i]) ); } END_LOOP ncount++; } /* k (location in path) */ } /* ln */ } /* iloop */ /* Now multiply the staple sum by the link, then update momentum */ FORALLSITES(i,st){ mult_su3_na( forwardlink[dir]+i, &(staple[i]), &tmat1 ); momentum = tmpmom[dir] + i; scalar_mult_sub_su3_matrix( momentum, &tmat1, eb3, momentum ); } END_LOOP
void d_plaquette_field_hist(su3_matrix **U_field, int Npowers, int *Nhist, double **hist, double **hist_bounds, double *ss_plaq, double *st_plaq) { /* su3mat is scratch space of size su3_matrix */ su3_matrix *su3mat; register int i,dir1,dir2; register int ipower,ihist; register site *s; register su3_matrix *m1,*m4; double *plaq_power, *step_hist; su3_matrix mtmp; double ss_sum,st_sum; double rtrace, rtrace3; msg_tag *mtag0,*mtag1; ss_sum = st_sum = 0.0; #ifdef HISQ_DUMP_PLAQ_INTO_FILE FILE *fp; char plaq_file_name[300]; #endif /* HISQ_DUMP_PLAQ_INTO_FILE */ su3mat = (su3_matrix *)malloc(sizeof(su3_matrix)*sites_on_node); if(su3mat == NULL) { printf("plaquette: can't malloc su3mat\n"); fflush(stdout); terminate(1); } /* zero out the histogram */ for(ipower=0;ipower<Npowers;ipower++) { for(ihist=0;ihist<Nhist[ipower];ihist++) { hist[ipower][ihist]=0.0; } } /* array with powers of (3-plaquette) */ plaq_power=(double*)malloc(sizeof(double)*Npowers); /* array with step sizes */ step_hist=(double*)malloc(sizeof(double)*Npowers); for(ipower=0;ipower<Npowers;ipower++) { step_hist[ipower]= (hist_bounds[ipower][1]-hist_bounds[ipower][0])/Nhist[ipower]; } #ifdef HISQ_DUMP_PLAQ_INTO_FILE sprintf( plaq_file_name, "plaq_W_node%04d.dat", this_node ); fp = fopen( plaq_file_name, "wt" ); #endif /* HISQ_DUMP_PLAQ_INTO_FILE */ for(dir1=YUP;dir1<=TUP;dir1++){ for(dir2=XUP;dir2<dir1;dir2++){ mtag0 = start_gather_field( U_field[dir2], sizeof(su3_matrix), dir1, EVENANDODD, gen_pt[0] ); mtag1 = start_gather_field( U_field[dir1], sizeof(su3_matrix), dir2, EVENANDODD, gen_pt[1] ); FORALLSITES(i,s){ m1 = &(U_field[dir1][i]); m4 = &(U_field[dir2][i]); mult_su3_an(m4,m1,&su3mat[i]); } wait_gather(mtag0); wait_gather(mtag1); FORALLSITES(i,s){ mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); if(dir1==TUP ) { rtrace = (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); st_sum += rtrace; } else { rtrace = (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); ss_sum += rtrace; } // printf("Plaq i=%d, dir1=%d, dir2=%d: %f %f\n", // i,dir1,dir2,rtrace_s,rtrace_t); #ifdef HISQ_DUMP_PLAQ_INTO_FILE fprintf( fp, "%18.12g\n", rtrace ); #endif /* HISQ_DUMP_PLAQ_INTO_FILE */ /* powers of (3-plaquette) */ rtrace3=3.0-rtrace; plaq_power[0]=rtrace3; for(ipower=1;ipower<Npowers;ipower++) { plaq_power[ipower]=plaq_power[ipower-1]*rtrace3; } /* find histogram entry */ for(ipower=0;ipower<Npowers;ipower++) { if( (plaq_power[ipower]>hist_bounds[ipower][0]) && (plaq_power[ipower]<hist_bounds[ipower][1]) ) { ihist=(int)( (plaq_power[ipower]-hist_bounds[ipower][0])/ step_hist[ipower] ); hist[ipower][ihist]+=1.0; } } } cleanup_gather(mtag0); cleanup_gather(mtag1); }
void d_plaquette(double *ss_plaq,double *st_plaq) { /* su3mat is scratch space of size su3_matrix */ su3_matrix *su3mat; register int i,dir1,dir2; register site *s; register su3_matrix *m1,*m4; su3_matrix mtmp; double ss_sum,st_sum; msg_tag *mtag0,*mtag1; ss_sum = st_sum = 0.0; su3mat = (su3_matrix *)malloc(sizeof(su3_matrix)*sites_on_node); if(su3mat == NULL) { printf("plaquette: can't malloc su3mat\n"); fflush(stdout); terminate(1); } for(dir1=YUP;dir1<=TUP;dir1++){ for(dir2=XUP;dir2<dir1;dir2++){ mtag0 = start_gather_site( F_OFFSET(link[dir2]), sizeof(su3_matrix), dir1, EVENANDODD, gen_pt[0] ); mtag1 = start_gather_site( F_OFFSET(link[dir1]), sizeof(su3_matrix), dir2, EVENANDODD, gen_pt[1] ); FORALLSITES(i,s){ m1 = &(s->link[dir1]); m4 = &(s->link[dir2]); mult_su3_an(m4,m1,&su3mat[i]); } wait_gather(mtag0); wait_gather(mtag1); FORALLSITES(i,s){ #ifdef SCHROED_FUN if(dir1==TUP ){ if(s->t==(nt-1)){ mult_su3_nn( &su3mat[i], &(s->boundary[dir2]), &mtmp); } else{ mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); } st_sum += realtrace_su3((su3_matrix *)(gen_pt[1][i]), &mtmp); } else if(s->t > 0){ mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); ss_sum += realtrace_su3((su3_matrix *)(gen_pt[1][i]), &mtmp); } #else mult_su3_nn( &su3mat[i], (su3_matrix *)(gen_pt[0][i]), &mtmp); if(dir1==TUP )st_sum += (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); else ss_sum += (double) realtrace_su3((su3_matrix *)(gen_pt[1][i]),&mtmp); #endif } cleanup_gather(mtag0); cleanup_gather(mtag1); } }
/* update the momenta with the gauge force */ void imp_gauge_force_cpu( Real eps, field_offset mom_off ){ register int i,dir; register site *st; su3_matrix tmat1,tmat2; register Real eb3; register anti_hermitmat* momentum; su3_matrix *staple, *tempmat1; /* lengths of various kinds of loops */ int *loop_length = get_loop_length(); /* number of rotations/reflections for each kind */ int *loop_num = get_loop_num(); /* table of directions, 1 for each kind of loop */ int ***loop_table = get_loop_table(); /* table of coefficients in action, for various "representations" (actually, powers of the trace) */ Real **loop_coeff = get_loop_coeff(); int max_length = get_max_length(); int nloop = get_nloop(); int nreps = get_nreps(); #ifdef GFTIME int nflop = 153004; /* For Symanzik1 action */ double dtime; #endif int j,k; int *dirs,length; int *path_dir,path_length; int ln,iloop; Real action,act2,new_term; int ncount; char myname[] = "imp_gauge_force"; #ifdef GFTIME dtime=-dclock(); #endif dirs = (int *)malloc(max_length*sizeof(int)); if(dirs == NULL){ printf("%s(%d): Can't malloc dirs\n",myname,this_node); terminate(1); } path_dir = (int *)malloc(max_length*sizeof(int)); if(path_dir == NULL){ printf("%s(%d): Can't malloc path_dir\n",myname,this_node); terminate(1); } staple = (su3_matrix *)special_alloc(sites_on_node*sizeof(su3_matrix)); if(staple == NULL){ printf("%s(%d): Can't malloc temporary\n",myname,this_node); terminate(1); } tempmat1 = (su3_matrix *)special_alloc(sites_on_node*sizeof(su3_matrix)); if(tempmat1 == NULL){ printf("%s(%d): Can't malloc temporary\n",myname,this_node); terminate(1); } eb3 = eps*beta/3.0; /* Loop over directions, update mom[dir] */ for(dir=XUP; dir<=TUP; dir++){ FORALLSITES(i,st)for(j=0;j<3;j++)for(k=0;k<3;k++){ staple[i].e[j][k]=cmplx(0.0,0.0); } END_LOOP ncount=0; for(iloop=0;iloop<nloop;iloop++){ length=loop_length[iloop]; for(ln=0;ln<loop_num[iloop];ln++){ /**printf("UPD: "); printpath( loop_table[iloop][ln], length );**/ /* set up dirs. we are looking at loop starting in "XUP" direction, rotate so it starts in "dir" direction. */ for(k=0;k<length;k++){ if( GOES_FORWARDS(loop_table[iloop][ln][k]) ){ dirs[k]=(dir+loop_table[iloop][ln][k] )% 4; } else { dirs[k]=OPP_DIR( (dir+OPP_DIR(loop_table[iloop][ln][k]))%4 ); } } path_length= length-1; /* generalized "staple" */ /* check for links in direction of momentum to be updated, each such link gives a contribution. Note the direction of the path - opposite the link. */ for(k=0;k<length;k++)if( dirs[k]==dir||dirs[k]==OPP_DIR(dir)) { if( GOES_FORWARDS(dirs[k]) ) for(j=0;j<path_length;j++) { path_dir[j] = dirs[(k+j+1)%length]; } if( GOES_BACKWARDS(dirs[k]) ) for(j=0;j<path_length;j++) { path_dir[path_length-1-j] = OPP_DIR(dirs[(k+j+1)%length]); } /**if(dir==XUP)printf("X_UPDATE PATH: "); printpath( path_dir, path_length );**/ path_product(path_dir,path_length, tempmat1); /* We took the path in the other direction from our old convention in order to get it to end up "at our site", so now take adjoint */ /* then compute "single_action" contribution to staple */ FORALLSITES(i,st){ su3_adjoint( &(tempmat1[i]), &tmat1 ); /* first we compute the fundamental term */ new_term = loop_coeff[iloop][0]; /* now we add in the higher representations */ if(nreps > 1){ node0_printf("WARNING: THIS CODE IS NOT TESTED\n"); exit(0); act2=1.0; action = 3.0 - realtrace_su3(&(st->link[dir]), &tmat1 ); for(j=1;j<nreps;j++){ act2 *= action; new_term += loop_coeff[iloop][j]*act2*(Real)(j+1); } } /* end if nreps > 1 */ scalar_mult_add_su3_matrix( &(staple[i]), &tmat1, new_term, &(staple[i]) ); } END_LOOP ncount++; } /* k (location in path) */ } /* ln */ } /* iloop */ /* Now multiply the staple sum by the link, then update momentum */ FORALLSITES(i,st){ mult_su3_na( &(st->link[dir]), &(staple[i]), &tmat1 ); momentum = (anti_hermitmat *)F_PT(st,mom_off); uncompress_anti_hermitian( &momentum[dir], &tmat2 ); scalar_mult_sub_su3_matrix( &tmat2, &tmat1, eb3, &(staple[i]) ); make_anti_hermitian( &(staple[i]), &momentum[dir] ); } END_LOOP