//  ISM.C
//  Author: Peter J. Meyer

#define SHOW_NOTICE

#define RANDOM_SEED 0
//  Define as 0 to use seconds-since-1970 or 
//  as non-zero to get a reproducible sequence of random numbers.

//  This program supports Ising and q-state Potts spin models 
//  (non-diluted, site-diluted and bond-diluted) 
//  on lattices of the following nine types 
//  (coordination number in parentheses):
//
//  2d:     square (4)         honeycomb (3)              
//          triangular (6)     double triangular (8)
//  3d:     cubic (6)          diamond (4)           
//          quadrilateral (8)      
//  4d:     hypercubic (8)     hyperdiamond (5)   

#define M		
//  Controls variable declarations and definitions in iss_var.h.
#include "iss.h"

static void preliminaries(char *argv[]);
static void zero_multiple_temperature_results(void);
static void perform_task(void);      

/*-----------------------------*/
void main(int argc, char *argv[])
{
preliminaries(argv);                    //  Below.

if ( argc == 1 )
    display_syntax();                   //  Does not return.

strupr(argv[1]);

if ( !strcmp(argv[1],"/F") )
    display_input_data_format();        //  Does not return.

#ifdef SHOW_NOTICE
show_notice();                          //  For U. of D. version.
#endif

system_date(session_start_date,ISO);
system_time(session_start_time,true);
//  If more than one input file then a session has multiple runs.

num_input_files = argc - 1;

if ( num_input_files > 1 )
    printf("Processing %d input files.\n",num_input_files);

for ( input_file_num=0; input_file_num<num_input_files; input_file_num++ )
    {
    if ( !read_command_line(input_file_num+1,argv) )     //  READ.c
        break;

    set_up_filenames();                     //  FILE_IO.C

    read_input_data();                      //  READ.C

    check_if_output_file_exists();          //  FILE_IO.C

    set_parameters();                       //  SETPARAM.C

    display_startup_info();                 //  TEXTOUT.C

    allocate_arrays();                      //  ALLOC.C

    if ( use_precomputed_nn_sites )
        precompute_nn_sites();              //  PRECOMP.C

    if ( multiple_temperatures_specified )
        zero_multiple_temperature_results();

    for ( temperature_num=0; temperature_num<num_temperatures; temperature_num++ )
        {
        temperature = temperatur[temperature_num];
        final_temperature = ( temperature_num == num_temperatures - 1 );
        //  Results file is displayed only when this becomes true
        //  (or user requests the program to stop).
        perform_task();                     //  below
        if ( escape_key_termination || stop_on_next_temperature )
            break;
        }

    free_arrays();                          //  ALLOC.C

    if ( escape_key_termination || stop_on_next_temperature )
        break;
    }

if ( NUM_PRNG1_CALLS() > 0 )
    {
    system_date(session_end_date,ISO);
    system_time(session_end_time,true);
    printf("\nRun started at %s %s",session_start_date,session_start_time);
    printf("\nRun ended   at %s %s",session_end_date,session_end_time);
    if ( (unsigned long)NUM_PRNG1_CALLS() < 2e9 )
        printf("\n%s was called %s times.\n",PRNG1_NAME,
            ultoa_commas((unsigned long)NUM_PRNG1_CALLS(),temp));
    else
        printf("\n%s was called %s million times.\n",PRNG1_NAME,
            ultoa_commas((unsigned long)(NUM_PRNG1_CALLS()/1e6),temp));
    }
}

/*-----------------------------------*/
static void preliminaries(char *argv[])
{
get_exe_name(argv);             //  READ.C

display_copyright();            //  TEXTOUT.C

if ( !( seed = RANDOM_SEED ) )
    seed = time(NULL);

INIT_PRNG1(seed*(seed+1)+1);
}

/*-----------------------------------------------*/
static void zero_multiple_temperature_results(void)
{
int i, j, k;

for ( i=0; i< MAX_NUM_TEMPERATURES; i++ )
    for ( j=0; j<NUM_MULTIPLE_RESULTS; j++ )
        for ( k=0; k<2; k++ )
            multiple_temperature_results[i][j][k] = 0.0;
}

/*--------------------------*/
static void perform_task(void)
{
int num_iterations_done;
// clock_t is #typedef'd as a long int in time.h.

system_date(run_start_date,ISO);
system_time(run_start_time,true);

task_start = clock();
pause_time = 0;

if ( goal_is_equilibration )
    perform_equilibrations();                                 //  EQUIL.C
else    
    num_iterations_done = get_percolation_threshold();       //  PERC.C

task_end = clock();

run_time = (( (double)task_end - task_start ) / CLOCKS_PER_SEC );
run_time -= pause_time;

//  Get end time
system_date(run_end_date,ISO);
system_time(run_end_time,true);

if ( goal_is_equilibration )
    write_equilibration_results();                      //  RESULTS.C
else
    write_percolation_results(num_iterations_done);     //  PERC_RESC.C
}