Exemple #1
0
OBSOLETE!  See update_rhmc.c
/********** update_rhmc_omelyan.c ******************************************/
/* MIMD version 7 */

/*
 See Takaishi and de Forcrand hep-lat/-0505020
 Update lattice.
    compute PHI for both factors in fermion determinant at beginning
	update U by (epsilon/2)*lambda
	compute X for light and strange quarks for each term in rational 
		function (or "both factors in det")
	update H, by epsilon
	update U by epsilon * (2-lambda)
	compute X for light and strange quarks for each term in rational 
		function
	update H, by epsilon
	update U by (epsilon/2)*lambda

 This routine does not refresh the antihermitian momenta.
 This routine begins at "integral" time, with H and U evaluated
 at same time.
  "lambda" is adjustable parameter.  At lambda=1 this is just two
  leapfrog steps of length epsilon. Note my lambda is 4X the lambda in
  Takaishi and de Forcrand and my epsilon is 1/2 theirs.  This makes
  epsilon the same as for the leapfrog algorithm.
  Omelyan "optimum lambda" is 4*0.1932
*/
#include "ks_imp_includes.h"	/* definitions files and prototypes */

#define mat_invert mat_invert_uml
/**#define mat_invert mat_invert_cg**/

int update()  {
  int step, iters=0;
  double startaction,endaction;
  Real xrandom;
  int i;
  su3_vector **multi_x;
  su3_vector *sumvec;
  Real lambda;
  int iphi;
  
  lambda = 0.8;
  node0_printf("Omelyan integration, steps= %d eps= %e lambda= %e\n",steps,epsilon,lambda);
  if (steps %2 != 0 ){
    node0_printf("BONEHEAD! need even number of steps\n");
    exit(0);
  }
  
  /* allocate space for multimass solution vectors */
  multi_x = (su3_vector **)malloc(max_rat_order*sizeof(su3_vector *));
  if(multi_x == NULL){
    printf("update: No room for multi_x\n");
    terminate(1);
  }
  for(i=0;i<max_rat_order;i++) 
    multi_x[i]=(su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
  sumvec = (su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
  
  /* refresh the momenta */
  ranmom();
  
  /* generate a pseudofermion configuration only at start*/
  for(iphi = 0; iphi < n_pseudo; iphi++){
    grsource_imp_rhmc( F_OFFSET(phi[iphi]), &(rparam[iphi].GR), EVEN,
		       multi_x,sumvec, rsqmin_gr[iphi], niter_gr[iphi]);
  }
  
  /* find action */
  startaction=d_action_rhmc(multi_x,sumvec);
  /* copy link field to old_link */
  gauge_field_copy( F_OFFSET(link[0]), F_OFFSET(old_link[0]));
  
  /* do "steps" microcanonical steps (one "step" = one force evaluation)"  */
  for(step=2; step <= steps; step+=2){
    
    /* update U's and H's - see header comment */
    update_u(0.5*epsilon*lambda);
    update_h_rhmc( epsilon, multi_x);
    update_u(epsilon*(2.0-lambda));
    update_h_rhmc( epsilon, multi_x);
    update_u(0.5*epsilon*lambda);
    
    /* reunitarize the gauge field */
    rephase( OFF );
    reunitarize();
    rephase( ON );
    /*TEMP - monitor action*/ //if(step%6==0)d_action_rhmc(multi_x,sumvec);
    
  }	/* end loop over microcanonical steps */
  
  /* find action */
  /* do conjugate gradient to get (Madj M)inverse * phi */
  endaction=d_action_rhmc(multi_x,sumvec);
  /* decide whether to accept, if not, copy old link field back */
  /* careful - must generate only one random number for whole lattice */
#ifdef HMC
  if(this_node==0)xrandom = myrand(&node_prn);
  broadcast_float(&xrandom);
  if( exp( (double)(startaction-endaction) ) < xrandom ){
    if(steps > 0)
      gauge_field_copy( F_OFFSET(old_link[0]), F_OFFSET(link[0]) );
#ifdef FN
    invalidate_all_ferm_links(&fn_links);
    invalidate_all_ferm_links(&fn_links_dmdu0);
#endif
    node0_printf("REJECT: delta S = %e\n", (double)(endaction-startaction));
  }
  else {
    node0_printf("ACCEPT: delta S = %e\n", (double)(endaction-startaction));
  }
#else // not HMC
  node0_printf("CHECK: delta S = %e\n", (double)(endaction-startaction));
#endif // HMC
  
  /* free multimass solution vector storage */
  for(i=0;i<max_rat_order;i++)free(multi_x[i]);
  free(sumvec);
  
  if(steps > 0)return (iters/steps);
  else return(-99);
}
Exemple #2
0
OBSOLETE!! multi_x is no longer sized correctly for more than one pseudofermion
/********** update_omelyan.c ****************************************************/
/* MIMD version 7 */

/*
 See Takaishi and de Forcrand hep-lat/-0505020
 Update lattice.
 Two gauge steps for one fermion force step ("epsilon" is time for one fermion step)
	update U to epsilon*(1/4-alpha/2)
	Update H by epsilon*1/2*gauge_force
	update U to epsilon*(1/2-beta)
	Update H by epsilon*fermion_force
	update U to epsilon*(3/4+alpha/2)
	Update H by epsilon*1/2*gauge_force

	update U to epsilon*(5/4-alpha/2)
	Update H by epsilon*1/2*gauge_force
	update U to epsilon*(3/2+beta)
	Update H by epsilon*fermion_force
	update U to epsilon*(7/4+alpha/2)
	Update H by epsilon*1/2*gauge_force
	update U to epsilon*(2)

 This routine does not refresh the antihermitian momenta.
 This routine begins at "integral" time, with H and U evaluated
 at same time.
  "alpha" and "beta" are adjustable parameters.  At alpha=beta=0 this
   is just leapfrog integration.
  Omelyan "optimum alpha" is 2*(0.25-0.1932) ~ 0.1
*/
#include "ks_imp_includes.h"	/* definitions files and prototypes */

#define mat_invert mat_invert_uml
/**#define mat_invert mat_invert_cg**/

int update()  {
  int step, iters=0;
  Real final_rsq;
  double startaction,endaction,d_action();
  Real xrandom;
  int i,j; site *s;
  su3_vector *multi_x[MAX_RAT_ORDER];
  su3_vector *sumvec;
  Real alpha,beta;
  int iphi;
  
  alpha = 0.1;
  beta = 0.1;
  node0_printf("Omelyan integration, 2 gauge for one 1 fermion step, steps= %d eps= %e alpha= %e beta= %e\n",
	       steps,epsilon,alpha,beta);
  if (steps %2 != 0 ){
    node0_printf("BONEHEAD! need even number of steps\n");
    exit(0);
  }
  
  /* allocate space for multimass solution vectors */
  for(i=0;i<MAX_RAT_ORDER;i++) multi_x[i]=(su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
  sumvec = (su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
  
  /* refresh the momenta */
  ranmom();
  
  /* generate a pseudofermion configuration only at start*/
  for(iphi = 0; iphi < nphi; iphi++){
    grsource_imp_rhmc( F_OFFSET(phi[iphi]), &(rparam[iphi].GR), EVEN,
		       multi_x,sumvec, rsqmin_gr[iphi], niter_gr[iphi]);
  }

  /* find action */
  startaction=d_action_rhmc(multi_x,sumvec);
  /* copy link field to old_link */
  gauge_field_copy( F_OFFSET(link[0]), F_OFFSET(old_link[0]));
  
  /* do "steps" microcanonical steps (one "step" = one force evaluation)"  */
  for(step=2; step <= steps; step+=2){
    
    /* update U's and H's - see header comment */
    update_u( epsilon*( (0.25-0.5*alpha) ) );
    update_h_gauge( 0.5*epsilon);
    update_u( epsilon*( (0.5-beta)-(0.25-0.5*alpha) ) );
    update_h_fermion( epsilon, multi_x);
    update_u( epsilon*( (0.75+0.5*alpha)-(0.5-beta) ) );
    update_h_gauge( 0.5*epsilon);
    
    update_u( epsilon*( (1.25-0.5*alpha)-(0.75+0.5*alpha) ) );
    update_h_gauge( 0.5*epsilon);
    update_u( epsilon*( (1.5+beta)-(1.25-0.5*alpha) ) );
    update_h_fermion( epsilon, multi_x);
    update_u( epsilon*( (1.75+0.5*alpha)-(1.5+beta) ) );
    update_h_gauge( 0.5*epsilon);
    update_u( epsilon*( (2.0)-(1.75+0.5*alpha) ) );
    
    /* reunitarize the gauge field */
    rephase( OFF );
    reunitarize();
    rephase( ON );
    /*TEMP - monitor action*/ //if(step%6==0)d_action_rhmc(multi_x,sumvec);
    
  }	/* end loop over microcanonical steps */
  
  /* find action */
  /* do conjugate gradient to get (Madj M)inverse * phi */
  endaction=d_action_rhmc(multi_x,sumvec);
  /* decide whether to accept, if not, copy old link field back */
  /* careful - must generate only one random number for whole lattice */
#ifdef HMC
  if(this_node==0)xrandom = myrand(&node_prn);
  broadcast_float(&xrandom);
  if( exp( (double)(startaction-endaction) ) < xrandom ){
    if(steps > 0)
      gauge_field_copy( F_OFFSET(old_link[0]), F_OFFSET(link[0]) );
#ifdef FN
  invalidate_all_ferm_links(&fn_links);
  invalidate_all_ferm_links(&fn_links_dmdu0);
#endif
    node0_printf("REJECT: delta S = %e\n", (double)(endaction-startaction));
  }
  else {
    node0_printf("ACCEPT: delta S = %e\n", (double)(endaction-startaction));
  }
#else // not HMC
  node0_printf("CHECK: delta S = %e\n", (double)(endaction-startaction));
#endif // HMC
  
  /* free multimass solution vector storage */
  for(i=0;i<MAX_RAT_ORDER;i++)free(multi_x[i]);
  free(sumvec);
  
  if(steps > 0)return (iters/steps);
    else return(-99);
}
OBSOLETE!  See update_rhmc.c
/********** update.c ****************************************************/
/* MIMD version 7 */

/*
 Update lattice.
     compute PHI for both factors in fermion determinant at beginning
	update U by (epsilon/2)
	compute X for light and strange quarks for each term in rational 
		function ( or "both factors in det.")
	update H, full step
	update U to next time needed

 This routine does not refresh the antihermitian momenta.
 This routine begins at "integral" time, with H and U evaluated
 at same time.
*/
#include "ks_imp_includes.h"	/* definitions files and prototypes */

#define mat_invert mat_invert_uml
/**#define mat_invert mat_invert_cg**/

int update()  {
  int step, iters=0;
  double startaction,endaction;
#ifdef HMC
  Real xrandom;
#endif
  int i;
  su3_vector **multi_x;
  su3_vector *sumvec;
  int iphi;

  node0_printf("Leapfrog integration, steps= %d eps= %e\n",steps,epsilon);
  
  /* allocate space for multimass solution vectors */

  multi_x = (su3_vector **)malloc(max_rat_order*sizeof(su3_vector *));
  if(multi_x == NULL){
    printf("update: No room for multi_x\n");
    terminate(1);
  }
  for(i=0;i<max_rat_order;i++){
    multi_x[i]=(su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
    if(multi_x[i] == NULL){
      printf("update: No room for multi_x\n");
      terminate(1);
    }
  }

  sumvec = (su3_vector *)malloc( sizeof(su3_vector)*sites_on_node );
  
  /* refresh the momenta */
  ranmom();
  
  /* generate a pseudofermion configuration only at start*/
  // NOTE used to clear xxx here.  May want to clear all solutions for reversibility
  for(iphi = 0; iphi < n_pseudo; iphi++){
    grsource_imp_rhmc( F_OFFSET(phi[iphi]), &(rparam[iphi].GR), EVEN,
		       multi_x,sumvec, rsqmin_gr[iphi], niter_gr[iphi]);
  }

  /* find action */
  startaction=d_action_rhmc(multi_x,sumvec);
  /* copy link field to old_link */
  gauge_field_copy( F_OFFSET(link[0]), F_OFFSET(old_link[0]));
  
  /* do "steps" microcanonical steps"  */
  for(step=1; step <= steps; step++){
    
    /* update U's to middle of interval */
    update_u(0.5*epsilon);
    
    /* now update H by full time interval */
    update_h_rhmc( epsilon, multi_x);
    
    /* update U's by half time step to get to even time */
    update_u(epsilon*0.5);
    
    /* reunitarize the gauge field */
    rephase( OFF );
    reunitarize();
    rephase( ON );
    /*TEMP - monitor action*/if(step%4==0)d_action_rhmc(multi_x,sumvec);
    
  }	/* end loop over microcanonical steps */
  
  /* find action */
  /* do conjugate gradient to get (Madj M)inverse * phi */
  endaction=d_action_rhmc(multi_x,sumvec);
  /* decide whether to accept, if not, copy old link field back */
  /* careful - must generate only one random number for whole lattice */
#ifdef HMC
  if(this_node==0)xrandom = myrand(&node_prn);
  broadcast_float(&xrandom);
  if( exp( (double)(startaction-endaction) ) < xrandom ){
    if(steps > 0)
      gauge_field_copy( F_OFFSET(old_link[0]), F_OFFSET(link[0]) );
#ifdef FN
    invalidate_fermion_links(fn_links);
    //    invalidate_all_ferm_links(&fn_links);
    //    invalidate_all_ferm_links(&fn_links_dmdu0);
#endif
    node0_printf("REJECT: delta S = %e\n", (double)(endaction-startaction));
  }
  else {
    node0_printf("ACCEPT: delta S = %e\n", (double)(endaction-startaction));
  }
#else  // not HMC
  node0_printf("CHECK: delta S = %e\n", (double)(endaction-startaction));
#endif // HMC
  
  /* free multimass solution vector storage */
  for(i=0;i<max_rat_order;i++)free(multi_x[i]);
  free(sumvec);
  
  if(steps > 0)return (iters/steps);
  else return(-99);
}
Exemple #4
0
int update()  {
  int step, iters=0;
  int n;
  Real final_rsq;
#ifdef HMC_ALGORITHM
  double startaction,endaction,d_action();
  Real xrandom;
#endif
  imp_ferm_links_t** fn;

    /* refresh the momenta */
    ranmom();

    /* In this application, the number of naik terms is 1 or 2 only */
    n = fermion_links_get_n_naiks(fn_links);

    /* do "steps" microcanonical steps"  */
    for(step=1; step <= steps; step++){
 
#ifdef PHI_ALGORITHM
        /* generate a pseudofermion configuration only at start*/
	/* also clear xxx, since zero is our best guess for the solution
	   with a new random phi field. */
     	if(step==1){
	  restore_fermion_links_from_site(fn_links, PRECISION);
	  fn = get_fm_links(fn_links);
	  clear_latvec( F_OFFSET(xxx1), EVENANDODD );
	  grsource_imp( F_OFFSET(phi1), mass1, EVEN, fn[0]);
	  clear_latvec( F_OFFSET(xxx2), EVENANDODD );
	  grsource_imp( F_OFFSET(phi2), mass2, EVEN, fn[n-1]);
	}

#ifdef HMC_ALGORITHM
        /* find action */
        /* do conjugate gradient to get (Madj M)inverse * phi */
        if(step==1){
            /* do conjugate gradient to get (Madj M)inverse * phi */
	  restore_fermion_links_from_site(fn_links, PRECISION);
	  fn = get_fm_links(fn_links);
	    iters += ks_congrad( F_OFFSET(phi1), F_OFFSET(xxx1), mass1,
				 niter, nrestart, rsqmin, PRECISION, EVEN, 
				 &final_rsq, fn[0]);
	  restore_fermion_links_from_site(fn_links, PRECISION);
	  fn = get_fm_links(fn_links);
	    iters += ks_congrad( F_OFFSET(phi2), F_OFFSET(xxx2), mass2,
				 niter, nrestart, rsqmin, PRECISION, EVEN, 
				 &final_rsq, fn[n-1]);

     	    startaction=d_action();
            /* copy link field to old_link */
	    gauge_field_copy( F_OFFSET(link[0]), F_OFFSET(old_link[0]));
        }
#endif

	/* update U's to middle of interval */
     	update_u(0.5*epsilon);

#else /* "R" algorithm */
       	/* first update the U's to special time interval */
        /* and generate a pseudofermion configuration */
	/* probably makes most sense if nflavors1 >= nflavors2 */

       	update_u(epsilon*(0.5-nflavors1/8.0));
	clear_latvec( F_OFFSET(xxx1), EVENANDODD );
	restore_fermion_links_from_site(fn_links, PRECISION);
	fn = get_fm_links(fn_links);
     	grsource_imp( F_OFFSET(phi1), mass1, EVEN, fn[0]);

       	update_u(epsilon*((nflavors1-nflavors2)/8.0));
	clear_latvec( F_OFFSET(xxx2), EVENANDODD );
	restore_fermion_links_from_site(fn_links, PRECISION);
	fn = get_fm_links(fn_links);
     	grsource_imp( F_OFFSET(phi2), mass2, EVEN, fn[n-1]);

	/* update U's to middle of interval */
     	update_u(epsilon*nflavors2/8.0);
#endif

        /* do conjugate gradient to get (Madj M)inverse * phi */
	restore_fermion_links_from_site(fn_links, PRECISION);
	fn = get_fm_links(fn_links);
	if(n == 2){
	  iters += ks_congrad( F_OFFSET(phi1), F_OFFSET(xxx1), mass1,
		       niter, nrestart, rsqmin, PRECISION, EVEN, &final_rsq, fn[0] );
	  iters += ks_congrad( F_OFFSET(phi2), F_OFFSET(xxx2), mass2,
		       niter, nrestart, rsqmin, PRECISION, EVEN, &final_rsq, fn[1] );
	} else {
	iters += ks_congrad_two_src( F_OFFSET(phi1), F_OFFSET(phi2),
				     F_OFFSET(xxx1), F_OFFSET(xxx2),
				     mass1, mass2, niter, nrestart, rsqmin, 
				     PRECISION, EVEN, &final_rsq,
				     fn[0]);
	}

	dslash_site( F_OFFSET(xxx1), F_OFFSET(xxx1), ODD, fn[0]);
	dslash_site( F_OFFSET(xxx2), F_OFFSET(xxx2), ODD, fn[n-1]);
	/* now update H by full time interval */
    	update_h(epsilon);

#if 0
#ifdef HAVE_QIO
	{
	  char *filexml;
	  char recxml[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><title>Test fermion force field</title>";
	  char ansfile[128];
	  char rootname[] = "fermion_force_dump";

	  /* Do this at the specified interval */
	  if(step%3 == 1){
	    
	    /* Construct a file name */
	    sprintf(ansfile,"%s%02d",rootname,step);
	    /* Dump the computed fermion force from the site structure */
	    filexml = create_QCDML();
	    save_color_matrix_scidac_from_site(ansfile, filexml, 
		       recxml, QIO_PARTFILE,  F_OFFSET(mom[0]), 4, PRECISION);
	    free_QCDML(filexml);
	  }
	}
#endif
#endif

    	/* update U's by half time step to get to even time */
    	update_u(epsilon*0.5);

        /* reunitarize the gauge field */
	rephase( OFF );
        reunitarize();
	rephase( ON );

    }	/* end loop over microcanonical steps */

#ifdef HMC_ALGORITHM
    /* find action */
    /* do conjugate gradient to get (Madj M)inverse * phi */
    restore_fermion_links_from_site(fn_links, PRECISION);
    fn = get_fm_links(fn_links);
    iters += ks_congrad( F_OFFSET(phi1), F_OFFSET(xxx1), mass1,
			 niter, nrestart, rsqmin, PRECISION, EVEN, 
			 &final_rsq, fn[0]);
    iters += ks_congrad( F_OFFSET(phi2), F_OFFSET(xxx2), mass2,
			 niter, nrestart, rsqmin, PRECISION, EVEN, 
			 &final_rsq, fn[n-1]);
    endaction=d_action();
    /* decide whether to accept, if not, copy old link field back */
    /* careful - must generate only one random number for whole lattice */
    if(this_node==0)xrandom = myrand(&node_prn);
    broadcast_float(&xrandom);
    if( exp( (double)(startaction-endaction) ) < xrandom ){
	if(steps > 0)
	    gauge_field_copy( F_OFFSET(old_link[0]), F_OFFSET(link[0]) );
#ifdef FN
	invalidate_fermion_links(fn_links);
#endif
	node0_printf("REJECT: delta S = %e\n", (double)(endaction-startaction));
    }
    else {
	node0_printf("ACCEPT: delta S = %e\n", (double)(endaction-startaction));
    }
#endif

    if(steps > 0)return (iters/steps);
    else return(-99);
}