Exemple #1
0
double imp_gauge_action() {
    register int i;
    int rep;
    register site *s;
    complex trace;
    double g_action;
    double action,act2,total_action;
    su3_matrix *tempmat1;
    int length;

    /* these are for loop_table  */
    int ln,iloop;

    g_action=0.0;

    tempmat1 = (su3_matrix *)special_alloc(sites_on_node*sizeof(su3_matrix));
    if(tempmat1 == NULL){
      printf("imp_gauge_action: Can't malloc temporary\n");
      terminate(1);
  }

    /* gauge action */
    for(iloop=0;iloop<NLOOP;iloop++){
	length=loop_length[iloop];
	/* loop over rotations and reflections */
	for(ln=0;ln<loop_num[iloop];ln++){

	    path_product( loop_table[iloop][ln] , length, tempmat1 );

	    FORALLSITES(i,s){
		trace=trace_su3( &tempmat1[i] );
		action =  3.0 - (double)trace.real;
		/* need the "3 -" for higher characters */
        	total_action= (double)loop_coeff[iloop][0]*action;
        	act2=action;
		for(rep=1;rep<NREPS;rep++){
		    act2 *= action;
		    total_action += (double)loop_coeff[iloop][rep]*act2;
		}

        	g_action  += total_action;

	    } END_LOOP /* sites */
	} /* ln */
    } /* iloop */
double imp_gauge_action() {
    register int i;
    int rep;
    register site *s;
    complex trace;
    double g_action;
    double action,act2,total_action;
    int length;

    /* these are for loop_table  */
    int ln,iloop;

    g_action=0.0;

    /* gauge action */
    for(iloop=0;iloop<NLOOP;iloop++){
	length=loop_length[iloop];
	/* loop over rotations and reflections */
	for(ln=0;ln<loop_num[iloop];ln++){

	    path_product( loop_table[iloop][ln] , length );

	    FORALLSITES(i,s){
		trace=trace_su3( &s->tempmat1 );
		action =  3.0 - (double)trace.real;
		/* need the "3 -" for higher characters */
        	total_action= (double)loop_coeff[iloop][0]*action;
        	act2=action;
		for(rep=1;rep<NREPS;rep++){
		    act2 *= action;
		    total_action += (double)loop_coeff[iloop][rep]*act2;
		}

        	g_action  += total_action;

	    } END_LOOP /* sites */
	} /* ln */
    } /* iloop */
Exemple #3
0
void hybrid_loop1(int tot_smear) {

  char myname[] = "hybrid_loop1";
  register int i,j,dir,r,t;
  int dir1=0,dir2=0,trans_path1=0,trans_path2=0;
  int disp[4];
  int nth,nxh;
  register site *s;
  su3_matrix tmat1,tmat2;
  su3_matrix *tmatp;
  Real *wils_loop1;
  su3_matrix *flux_links_f;
  su3_matrix *trans_links, *trans_links_f; 
  su3_matrix *flux_links;
  su3_matrix *tempmat1;
  
  /* Names of messages used to index "mtag" and "gen_pt" */
  /* NMSGS must not exceed N_POINTERS */
  enum{ M_S_LINK, M_F_LINKS_F, M_T_LINKS_F, M_STAP_POS1, 
	  M_STAP_NEG1, M_STAP_POS2, M_STAP_NEG2, NMSGS };
  
  msg_tag *mtag[NMSGS];

  /* Names of flux tube shapes built from transverse links 
     and on-axis links used to index "flux_links" */
  
  enum{ S_LINK, STAP_POS1, STAP_NEG1, STAP_POS2, STAP_NEG2, NFLUX };

  /* Names of transverse links 
     used to index "trans_path", "trans_links" and "trans_links_f" */
  enum{ XX, YY, ZZ, NTRANS };

  /* Names of space-shifted transverse links */
  /* used to index "trans_links_f" */
  enum{ TRANS_PATH1_F, TRANS_PATH2_F, T_LINK_F, NTRANS_F };
  
  /* Paths for transverse links */
  
  const link_path trans_path[NTRANS] =
    {
      { "XX",   2, {2,0,0,0}, {XUP, XUP, NODIR, NODIR} },
      { "YY",   2, {0,2,0,0}, {YUP, YUP, NODIR, NODIR} },
      { "ZZ",   2, {0,0,2,0}, {ZUP, ZUP, NODIR, NODIR} }
    };

  /* Names of flux tube shapes transported forward in time */
  /* Used to index "flux_links_f" */
  enum{ S_LINK_F, STAP_POS1_F, NFLUX_F };

  /* Names of loop observables */
  /* Used to index "wils_loop1" */
  enum{ W_LOOP1, STAP_SIG_GP1, STAP_PI_U1, STAP_DELTA_G1, NWLOOP1 };

  /* Check the rules */
  if(NMSGS > N_POINTERS){
    if(this_node == 0)fprintf(stderr,"%s: Aborted. gen_pt array too small.",myname);
    terminate(1);
  }

  if( nx != ny || nx != ny){
    if(this_node == 0)fprintf(stderr,"%s: Aborted. requires nx=ny=nz",myname);
    terminate(1);
  }
  
  /* Allocate space for observables */
//AB  nth = nt/2;  nxh = nx/2;
//CD  nth = nt;  nxh = nx/2;
  nth = max_t;  nxh = nx/2;
  wils_loop1 = (Real *)malloc(nth*nxh*sizeof(Real)*NWLOOP1);
  if(wils_loop1 == NULL){
    fprintf(stderr,"%s: CAN'T MALLOC wils_loop1\n",myname);
    fflush(stderr);
    terminate(1);
  }
  
  for(i=0;i<NWLOOP1;i++) for(t=0;t<nth;t++) for(r=0;r<nxh;r++)
    WILS_LOOP1(i,t,r) = 0.0;

  /* Allocate space for timeward shifted flux tube shapes */
  flux_links_f = 
    (su3_matrix *)malloc(sites_on_node*sizeof(su3_matrix)*NFLUX_F);
  if(flux_links_f == NULL){
    fprintf(stderr,"%s: CAN'T MALLOC flux_links_f\n",myname);
    fflush(stderr);
    terminate(1);
  }
  
  /* Allocate space for transverse link products */
  trans_links = 
    (su3_matrix *)malloc(NTRANS*sites_on_node*sizeof(su3_matrix));
  if(trans_links == NULL){
    fprintf(stderr,"%s: CAN'T MALLOC trans_links\n",myname);
    fflush(stderr);
    terminate(1);
  }
  
  /* Allocate space for shifted auxiliary link products */
  trans_links_f = 
    (su3_matrix *)malloc(NTRANS_F*sites_on_node*sizeof(su3_matrix));
  if(trans_links_f == NULL){
    fprintf(stderr,"%s: CAN'T MALLOC trans_links_f\n",myname);
    fflush(stderr);
    terminate(1);
  }
     
  tempmat1 = (su3_matrix *)malloc(sites_on_node*sizeof(su3_matrix));
  if(tempmat1 == NULL){
    printf("%s(%d): Can't malloc temporary\n",myname,this_node);
    terminate(1);
  }

  /* Compute and store products of transverse links */
  /* trans_links[i][j] is set to the link product for the
     jth path type that ends at site i */
  for(j = 0; j < NTRANS; j++){
    path_product(trans_path[j].dir, trans_path[j].length, tempmat1);
    FORALLSITES(i,s){
      su3mat_copy(tempmat1+i, TRANS_LINKS(i,j));
    }
  }
/* 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
/* 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