/*********************************************************
 * Generic field smoothing routine
 * Kari Rummukainen 1998-2002
 */

void smooth_FIELD(MATRIX *link[NDIM], FIELD *cphi, int d[NDIM],
		  double c_mul_0, double c_mul_1)
{
  /*   Block the Higgs field(s)
   */

  int i,dir,odir,first;
  msg_tag *tag0, *tag1;
  FIELD *tmp1, *tmp2, t;

  tmp1 = tmp_latfield( FIELD );
  tmp2 = tmp_latfield( FIELD );

  first = 1;
  foralldir(dir) if (d[dir]) {

    odir = opp_dir(dir);
    /* start gather - from up */
    tag0 = start_get( cphi, dir, EVENODD );
  
    /* multiply with 'up', use tmp1 as temporary */
    forallsites(i) {
      mult_adj_MATRIX_FIELD( link[dir][i], cphi[i], tmp1[i] );
    }
      
    /* and move up */
    tag1 = start_get( tmp1, odir, EVENODD );
      
    /* mult link with higgs, add to the original */
    if (first) {
      forallsites_wait(i,tag0) {
	mult_MATRIX_FIELD( link[dir][i], cphi[nb(dir,i)], tmp2[i] );
      } 
    } else {
      forallsites_wait(i,tag0) {
	mult_MATRIX_FIELD( link[dir][i], cphi[nb(dir,i)], t );
	add_FIELD( t, tmp2[i], tmp2[i] );
      }
    }
    first = 0;
      
    /* add the down-link */
    forallsites_wait(i,tag1) {
      add_FIELD( tmp1[nb(odir,i)], tmp2[i], tmp2[i] );
    }
      
  } /* directions */
    
  forallsites(i) {
    /* add the averaged field to the old field */
    scalar_mult_FIELD( cphi[i], c_mul_0, cphi[i] );
    scalar_mult_FIELD( tmp2[i], c_mul_1, cphi[i] );
  }

  free_tmp( tmp2 );
  free_tmp( tmp1 );
}

