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 );
}
Exemplo n.º 2
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 */