Esempio n. 1
0
// 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 eo_fermion_force_rhmc( Real eps, params_ratfunc *rf, 
			    su3_vector **multi_x, field_offset phi_off, 
			    Real my_rsqmin, int my_niter,
			    int cg_prec, int ff_prec, fermion_links_t *fl)
{
    // at different time steps

    Real final_rsq;
    int j;
    int order = rf->order;
    Real *residues = rf->res;
    Real *roots = rf->pole;
    imp_ferm_links_t **fn;

    // Compute ( M^\dagger M)^{-1} in xxx_even
    // Then compute M*xxx in temporary vector xxx_odd 
    /* See long comment at end of file */
	/* The diagonal term in M doesn't matter */
    //    load_ferm_links(fn);
    restore_fermion_links_from_site(fl, cg_prec);
    fn = get_fm_links(fl);

    /* Do the inversion for zero Naik term epsilon */
    ks_ratinv( phi_off, multi_x, roots, order, my_niter,
	       my_rsqmin, cg_prec, EVEN, &final_rsq, fn[0], 0, 0. );

    /* Do dslash for zero Naik term epsilon */
    for(j=0;j<order;j++){ dslash_field( multi_x[j], multi_x[j], ODD, fn[0] ); }

    eo_fermion_force_multi( eps, &(residues[1]), multi_x, order, ff_prec, fl );
}
Esempio n. 3
0
// fermion force update grouping pseudofermions with the same path coeffs
int update_h_fermion( Real eps, su3_vector **multi_x ){
  int iphi,jphi;
  Real final_rsq;
  int i,j,n;
  int order, tmporder;
  Real *residues,*allresidues;
  Real *roots;
  int iters = 0;
  imp_ferm_links_t **fn;

  /* Algorithm sketch: assemble multi_x with all |X> fields,
     then call force routine for each part (so far we have to parts:
     zero correction to Naik and non-zero correction to Naik */

  allresidues = (Real *)malloc(n_order_naik_total*sizeof(Real));

  // Group the fermion force calculation according to sets of like
  // path coefficients.
  tmporder = 0;
  iphi = 0;
#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ )
  n = fermion_links_get_n_naiks(fn_links);
#else
  n = 1;
#endif
  for( i=0; i<n; i++ ) {
    for( jphi=0; jphi<n_pseudo_naik[i]; jphi++ ) {
      restore_fermion_links_from_site(fn_links, prec_md[iphi]);
      fn = get_fm_links(fn_links);

      // Add the current pseudofermion to the current set
      order = rparam[iphi].MD.order;
      residues = rparam[iphi].MD.res;
      roots = rparam[iphi].MD.pole;

      // Compute ( M^\dagger M)^{-1} in xxx_even
      // Then compute M*xxx in temporary vector xxx_odd 
      /* See long comment at end of file */
	/* The diagonal term in M doesn't matter */
      iters += ks_ratinv( F_OFFSET(phi[iphi]), multi_x+tmporder, roots, order, 
			  niter_md[iphi], rsqmin_md[iphi], prec_md[iphi], EVEN, 
			  &final_rsq, fn[i], 
			  i, rparam[iphi].naik_term_epsilon );

      for(j=0;j<order;j++){
	dslash_field( multi_x[tmporder+j], multi_x[tmporder+j],  ODD,
		      fn[i]);
	allresidues[tmporder+j] = residues[j+1];
	// remember that residues[0] is constant, no force contribution.
      }
    tmporder += order;
    iphi++;
    }
  }

#ifdef MILC_GLOBAL_DEBUG
  node0_printf("update_h_rhmc: MULTI_X ASSEMBLED\n");fflush(stdout);
  node0_printf("update_h_rhmc: n_distinct_Naik=%d\n",n);
  for(j=0;j<n;j++)
    node0_printf("update_h_rhmc: orders[%d]=%d\n",j,n_orders_naik[j]);
#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ )
  for(j=0;j<n;j++)
    node0_printf("update_h_rhmc: masses_Naik[%d]=%f\n",j,fn_links.hl.eps_naik[j]);
#endif
  fflush(stdout);
#endif /* MILC_GLOBAL_DEBUG */

  restore_fermion_links_from_site(fn_links, prec_ff);
  eo_fermion_force_multi( eps, allresidues, multi_x,
			  n_order_naik_total, prec_ff, fn_links );

  free(allresidues);
  return iters;
} /* update_h_fermion */