/******** setup.c *********/
/* MIMD code version 3 */

#include "lattice.h"

/* Each node has a params structure for passing simulation parameters */

void load_config(int status);
void coldlat(); void hotlat();
void setcouplings();

/* SETUP ROUTINES */

int setup()
{
  int i,rstatus,restart,j;
  int nx,ny,nz,nt,size[NDIM];
  FILE *fil;
  
  /* On node zero, read lattice size, seed, nflavors and send to others */
  /* print banner */
  if (this_node == 0) {
    printf("--------------------------------------\n");
#ifdef Higgs
    printf("SU3 + adjoint Higgs in %d dimensions\n",NDIM);
#else
    printf("SU3 gauge in %d dimensions\n",NDIM);
#endif
    printf("Based on MILC MIMD version 3\n");
    printf("Machine = %s, with %d nodes\n",machine_type(),numnodes());
    printf("Overrelaxed/quasi-heat bath algorithm\n");

    if ((fil = fopen(paramname,"r")) == NULL) halt(" ** No parameter file?");
    printf("\n READING LATTICE SIZE FROM PARAMETER FILE:\n");
  }

  nx = size[XUP] = get_i(fil,"nx",1);
  ny = size[YUP] = get_i(fil,"ny",1);
  nz = size[ZUP] = get_i(fil,"nz",1);
#if NDIM == 4
  nt = size[TUP] = get_i(fil,"nt",1);
#endif

  /**************************************************
   * Initialize the layout and gather functions 
   */
  setup_lattice(size);

  printf0("\n READING REST OF THE PARAMETER FILE:\n");

  mc_steps =       get_i(fil,"micro steps",1);
  n_measurement =  get_i(fil,"n_measurement",1);
#ifdef HIGGS
  n_correlation =  get_i(fil,"n_correlation",1);
  w_correlation =  get_i(fil,"w_correlation",1);
#endif
  n_save =         get_i(fil,"n_save",1);

#ifdef HIGGS
  n_blocking =     get_i(fil,"blocking levels",1);
  for (j=n_bop=0; j<n_blocking; j++) {
    char level[100];
    int bl[NDIM];
    sprintf(level,"level %d",j);
    b_level[j] =   get_i(fil,level,1);
    if (b_level[j]) n_bop++;
    if ((nx % (1<<j)) || (ny % (1<<j)) || nx / (1<<j) < 2 || ny / (1<<j) < 2)
      halt("* Correlation function blocking error");
    
    /* and initialize blocking levels too here */
    bl[XUP] = bl[YUP] = j; bl[ZUP] = 0;
    set_blocking_level(bl);
  }
  reset_blocking_level();

  if (this_node == 0) {
    printf("Measured blocking levels ");
    for (j=0; j<n_blocking; j++) if (b_level[j]) printf("%d ",j);
    printf("\n");
  
    fclose(fil);
  }
  
#endif

  g_sync();
  
  if (this_node == 0) {
    if ((fil = fopen(statname,"r")) == NULL) halt(" ** No status file?");
    printf("\n READING STATUS FILE\n");
  }

  restart      = get_i(fil,"restart",1);
  n_iteration  = get_i(fil,"n_iteration",1);
  n_thermal    = get_i(fil,"n_thermal",1);
  seed         = get_i(fil,"seed",1);

  /* initialize the node random number generator */
  initialize_prn(seed);

  if (restart) {
    printf0(" ++++++++++++++ Reading restart info\n");
    
    rstatus    = get_i(fil,"run status",1);
    iteration  = get_i(fil,"iteration",1);
    timeu      = get_d(fil,"time: gauge",0);
#ifdef HIGGS
    timea      = get_d(fil,"time: higgs",0);
#endif
    timerest   = get_d(fil,"time: rest",0);

    if (rstatus == 1) printf0(" ++ Restarting thermalization\n");
    else if (iteration < n_iteration) printf0(" ++ Restarting the run\n");
    else {
      printf0(" ++ Starting a new run\n");
      restart = 0;
    }
  }
  
  if (!restart) {
    rstatus = 1;
    iteration = 0;
    timeu = timea = timerest = 0;
  }

  if (this_node == 0) fclose(fil);
    
  if (this_node == 0) {
    if ((fil = fopen(betaname,"r")) == NULL) halt("*** no beta-file");
    printf(" READING BETA-FILE\n");
  }
  betag      = get_d(fil,"betag",1);
#ifdef HIGGS
  p_x        = get_d(fil,"x",1);
  p_y        = get_d(fil,"y",1);
#endif

  if (this_node == 0) fclose(fil);

  /* and set the coupling constants */
  setcouplings();

#ifdef HIGGS  
  corrlen = nz/2 + 1;
  n_corr  = N_CORR*n_bop;
#endif

  return(rstatus);
}



/*********************************************************
 * load in configuration
 */

void load_config(int status)
{
  int i;
  int stat;
  double t;
  FILE * fil;

  if (this_node == 0) {
    i = ((fil = fopen(confname,"r")) != NULL);
    if (i) {
      printf(" - Reading the configuration\n");
      stat = 1;
    } else {
      printf(" ** Warning: no configuration file\n");
      stat = 0;
    }
  }
  broadcast_int(&stat);

  if (stat == 1) {
    t = cputime();
    restore_binary(fil);
    reunitarize(U);
    if(this_node==0){
      printf("Time for getting lattice = %le seconds\n",cputime()-t);
      fclose(fil);
    }
  } else {
#if NDIM == 4
    coldlat();
#else
    hotlat();
#endif
  }
}


/**********************************************************/


void 
coldlat()  
{
  /* sets link matrices to unit matrices */
  register int i,j,k,dir;

  forallsites(i){
#ifdef HIGGS
    for (j=0; j<8; j++) ahiggs[i].l[j] = 0.5;
#endif
    foralldir(dir) {
      for(j=0; j<3; j++)  {
	for(k=0; k<3; k++)  {
	  if (j != k) U[dir][i].e[j][k] = cmplx(0.0,0.0);
	  else U[dir][i].e[j][k] = cmplx(1.0,0.0);
	}
      }
    }
  }
  if(this_node==0)printf(" -- cold lattice loaded\n");
}


/**********************************************************/


void hotlat()  
{
  /* sets link matrices to random su3 */
  register int i,j,k,dir;

  forallsites(i){
#ifdef HIGGS
    for (j=0; j<8; j++) ahiggs[i].l[j] = 0.4 * ( 0.5 - dran() );
#endif
    foralldir(dir) random_su3P( &(U[dir][i]), 8 ); /* 8 hits only */
  }
  if(this_node==0)printf(" -- HOT lattice loaded\n");
}

