/******** setup.c *********/
/* MIMD version 6 */
#define IF_OK if(status==0)

/* Modifications ...
   9/03/96 Added reload_parallel for gauge fields C.D.
   9/03/96 Added unitarity checking C.D. */

#include "./include/includes.h"

char *mytime( const struct tm *timeptr )
{
    static char result[26];

    sprintf( result, "%02d%02d%02d_%02d%02d%02d",
	     timeptr->tm_year - 100, timeptr->tm_mon + 1, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec );
    return result;
}

int setup_KE( char *par_file )
{
    void initial_set( FILE *f );
    char filename[MAXFILENAME];
    FILE *f;

    debug();

/*  JuBE: kernel_E.input para file */
    if( ( f = fopen( "kernel_E.input", "r" ) ) == 0 && mynode_KE(  ) == 0 )
    {
        printf( "ERROR setup: missing parameter file\n" );
        terminate_KE( 0 );
    }

    /* initial output1 */
    if( this_node == 0 )
    {
/*     JuBE: output file changed */
        if( ( file_o1 = fopen( "kernel_E.output", "a" ) ) == 0 )
        {
            printf( "ERROR setup: cannot open output1 file\n" );
            exit( 0 );
        }
        fflush( 0 );
    }

    memsize=0; /* bit optimistic */
    debugflag=0;
    
    /* print banner, get volume, seed */
    initial_set( f );
    /* Initialize the layout functions, which decide where sites live */
    setup_layout_KE(  );
    /* initialize the node random number generator */
    ranstart(  );

    /* allocate space for lattice, set up coordinate fields */
    make_lattice(  );
    /* set up neighbor pointers and comlink structures */
    make_nn_gathers(  );

    /* load lattice */
    reload_lattice( startflag, filename );
    convert_gauge();
    
    debug();

    return 0;
}

/* read parameters */
void initial_set( FILE * f )
{
    int status;
    char latstart[MAXFILENAME], propend[MAXFILENAME], eigstart[MAXFILENAME];
    time_t now;
    char *mytime( const struct tm *timeptr );
    char parid[256];
    int m;

    status = 0;
    /* print banner */
    if( this_node == 0 )
    {
        now = time( NULL );
        fprintf( file_o1, "initial_set: A simple QCD benchmark -- %s --\n", mytime( localtime( &now ) ) );
    }
    node0_fprintf( file_o1, "initial_set: Based on MILC v6\n" );
    node0_fprintf( file_o1, "initial_set: Machine = %s, with %d nodes\n", machine_type_KE(  ), numnodes_KE(  ) );

    /* read in parameters - general */
    IF_OK status += get_i_KE( f, "nx", &nx );
    IF_OK status += get_i_KE( f, "ny", &ny );
    IF_OK status += get_i_KE( f, "nz", &nz );
    IF_OK status += get_i_KE( f, "nt", &nt );

    /* parameters */
    IF_OK status += get_f( f, "mass_wilson", &mass_wilson );
    kappa=1.0/(2*mass_wilson+8.0);

    /* some general things */
    IF_OK status += get_i_KE( f, "max_cg_iters", &max_cg_iters );
    IF_OK status += get_i_KE( f, "verbose", &verbose );

    g_sync_KE(  );

    if( status )
        terminate_KE( 1 );

    node0_fprintf( file_o1, "initial_set: Done\n" );

    volume = nx * ny * nz * nt;
}

void convert_gauge()
{
#if LINKDIST_32 == 4
    int i;
    for (i=0;i<sites_on_node*4*18;i++)
        gauge_32[i]=(float)(*((double *)gauge + i));
#endif
#if LINKDIST_32 == 8
    int i, dir, a;
    site *s;
    su3_matrix mat;
    msg_tag *tag[4];


    FORALLSITES( i, s ) 
        for ( dir = XUP; dir <= TUP; dir++ )
            for (a=0;a<18;a++)
                gauge_32[18*(8 * i + dir)+a] = (float)(*((double *)gauge + 18*(4 * i + dir)+a));

    for ( dir = XUP; dir <= TUP; dir++ )
    {
        tag[dir] = start_gather_from_temp( &( gauge[dir] ), sizeof( su3_matrix ), 4 * sizeof( su3_matrix ),
                OPP_DIR( dir ), EVENANDODD, gen_pt[dir] );
        wait_gather_KE( tag[dir] );
    }
    FORALLSITES( i, s ) 
        for ( dir = XUP; dir <= TUP; dir++ )
        {
            su3_adjoint_KE(( su3_matrix * ) (gen_pt[dir][i]), &mat);
            for (a=0;a<18;a++)
                gauge_32[18*(8 * i + OPP_DIR( dir ))+a] = (float)(*((double *)(&mat)+a));
        }
    for ( dir = XUP; dir <= TUP; dir++ )
        cleanup_gather( tag[dir] );

#endif
}
