// READ.C
// Functions mainly concerned with data input
// © 2021 Peter J. Meyer
#include "iss.h"
// Parameters for the simulation are obtained from an input data file.
// The command line requires only the file name.
static void read_lattice_type(void);
static int read_numeric_parameter_value(double *param,
double min_value, double max_value, char *param_name);
static int read_rational_numeric_parameter_value(double *param,
double min_value, double max_value, char *param_name);
static int read_alpha_parameter_value(char type[],
const char types[][2][30], char *type_name);
static int read_yn_parameter_value(void);
// When run from the compiler argv[0] is the full path, but when run at
// the command prompt argv[0] is just the first command line argument.
/*---------------------------*/
void get_exe_name(char *argv[])
{
char *ptr = strrchr(argv[0],'\\');
if ( ptr == NULL )
strcpy(exe_name,argv[0]);
else
strcpy(exe_name,++ptr);
_strupr(exe_name);
if ( strstr(exe_name,".EXE") == NULL )
strcat(exe_name,".EXE");
}
// Get name of input data file.
// Construct names of output data file and of map file.
/*--------------------------------------*/
int read_command_line(int i, char *argv[])
{
strcpy(input_filepath,argv[i]);
strupr(input_filepath);
if ( strchr(input_filepath,'.') == NULL ||
strcmp(".IN",strrchr(input_filepath,'.')) )
{
printf("\nInput data file = %s. "
"Name must have extension \".IN\".\n\n",input_filepath);
return ( false );
}
return ( true );
}
/*----------------------*/
void read_input_data(void)
{
int i;
char *ptr;
FILE *input_file;
double d;
// Zero temperatures array
i = MAX_NUM_TEMPERATURES;
while ( i )
temperatur[--i] = 0;
num_temperatures = 0;
if ( !open_file(input_filepath,"rt",&input_file) )
display_file_error_message("open","input data",input_filepath);
// Does not return.
while ( read_line(input_file) )
{
if ( !*line ) // if empty line
continue;
// Get lattice type.
if ( strstr(line,"lattice type:") == line )
{
read_lattice_type();
lattice_type_specified = true;
// Only one of the following will be true.
honeycomb_lattice = !strcmp(lattice_type,"HON");
square_lattice = !strcmp(lattice_type,"SQU");
triangular_lattice = !strcmp(lattice_type,"TRI");
double_triangular_lattice = !strcmp(lattice_type,"DTR");
cubic_lattice = !strcmp(lattice_type,"CUB");
diamond_lattice = !strcmp(lattice_type,"DIA");
quadrilateral_lattice = !strcmp(lattice_type,"QUA");
hypercubic_lattice_4d = !strcmp(lattice_type,"HC4");
hyperdiamond_lattice_4d = !strcmp(lattice_type,"HD4");
#if TETRAHEDRAL_LATTICE_IMPLEMENTED
tetrahedral_lattice = !strcmp(lattice_type,"TET");
#endif
// Set flag to show if lattice is such that direction table
// depends on parity of site location.
direction_table_is_parity_dependent =
honeycomb_lattice || diamond_lattice || hyperdiamond_lattice_4d;
}
// Get numerical parameters.
else if ( strstr(line,"lattice size:") == line )
{
// Read size.
if ( read_numeric_parameter_value(&d,MIN_SIZE,MAX_SIZE,"lattice size") )
{
size = (int)d;
size_specified = true;
}
}
else if ( strstr(line,"q-value:") == line )
{
// Read q-value.
if ( read_numeric_parameter_value(&d,MIN_Q_VALUE,MAX_Q_VALUE,"q-value") )
{
q = (int)d;
q_value_specified = true;
}
}
else if ( strstr(line,"site concentration:") == line )
{
// Read site concentration
if ( read_numeric_parameter_value(&site_concentration,
MIN_CONCENTRATION,MAX_CONCENTRATION,"site concentration") )
site_concentration_specified = true;
}
else if ( strstr(line,"bond concentration:") == line )
{
// Read bond concentration
if ( read_numeric_parameter_value(&bond_concentration,
MIN_CONCENTRATION,MAX_CONCENTRATION,"bond concentration") )
bond_concentration_specified = true;
}
else if ( strstr(line,"temperature:") == line
|| strstr(line,"temperatures:") == line )
{
// Read one or more temperatures.
strcpy(temp,strchr(line,':')+1);
_strlwr(temp);
i = num_temperatures;
loop
{
remove_leading_spaces(temp);
use_critical_temperature = !memcmp(temp,"critical",8);
if ( use_critical_temperature )
temperatur[i++] = -1;
else
{
if ( !*temp )
break;
if ( !strchr("0123456789+-.",temp[0]) )
display_input_data_error("temperature"); // Does not return.
d = atof(temp);
if ( d < MIN_TEMPERATURE || d > MAX_TEMPERATURE )
display_input_data_error("temperature"); // Does not return.
temperatur[i++] = d;
}
if ( ( ptr = strchr(temp,',') ) == NULL )
break; // no more temperatures
strcpy(temp1,temp);
ptr = strchr(temp1,',') + 1;
strcpy(temp,ptr);
}
num_temperatures = i;
}
else if ( strstr(line,"number of configurations:") == line )
{
// Read number of configurations.
if ( read_numeric_parameter_value(&d,1,
MAX_NUM_CONFIGURATIONS,"number of configurations") )
{
num_configurations = (int)d;
num_configurations_specified = true;
}
}
else if ( strstr(line,"number of spin assignments:") == line )
{
// Read number of configurations.
if ( read_numeric_parameter_value(&d,1,
MAX_NUM_SPIN_ASSIGNMENTS,"number of spin assignments") )
{
num_spin_assignments = (int)d;
num_spin_assignments_specified = true;
}
}
else if ( strstr(line,"number of repetitions:") == line )
{
// Read number of repetitions
if ( read_numeric_parameter_value(&d,1,
MAX_NUM_REPETITIONS,"number of repetitions") )
{
num_repetitions = (int)d;
num_repetitions_specified = true;
}
}
else if ( strstr(line,"number of time slices:") == line )
{
// Read number of time slices.
if ( read_numeric_parameter_value(&d,MIN_NUM_TIME_SLICES,
MAX_NUM_TIME_SLICES,"number of time slices") )
{
num_time_slices = (int)d;
num_time_slices_specified = true;
}
}
else if ( strstr(line,"step length:") == line )
{
// Read step length (mcs between time slices).
if ( read_numeric_parameter_value(&d,1,
MAX_STEP_LENGTH,"step length") )
{
step_length = (int)d;
step_length_specified = true;
}
}
else if ( strstr(line,"percentage range for mean:") == line )
{
// Read percentage range for mean magnetization, internal energy, specific heat.
if ( read_numeric_parameter_value(&d,MIN_PERCENTAGE_RANGE_FOR_MEAN,
MAX_PERCENTAGE_RANGE_FOR_MEAN,"percentage range for mean") )
{
percentage_range_for_mean = (int)d;
percentage_range_for_mean_specified = true;
}
}
else if ( strstr(line,"initial magnetization:") == line )
{
// Read initial magnetization.
if ( read_rational_numeric_parameter_value(&initial_magnetization,
-1.0,+1.0,"initial magnetization") )
initial_magnetization_specified = true;
}
else if ( strstr(line,"precision:") == line )
{
// Read number of decimal places in required precision for
// determination of percolation threshold.
if ( read_numeric_parameter_value(&d,
MIN_PRECISION,MAX_PRECISION,"precision") )
{
num_decimal_places = (int)d;
precision_specified = true;
}
}
else if ( strstr(line,"major axis:") == line )
{
// Read major axis.
if ( read_numeric_parameter_value(&d,
MIN_MAJOR_AXIS,MAX_MAJOR_AXIS,"major axis") )
{
major_axis = (int)d;
major_axis_specified = true;
}
}
// Read textual parameters.
#if DOES_PERCOLATION_THRESHOLDS
else if ( strstr(line,"goal:") == line )
{
g_type = read_alpha_parameter_value(goal, goals, "goal");
goal_specified = true;
goal_is_equilibration = ( !strcmp(goal,"SP") || !strcmp(goal,"EQ") );
goal_is_site_percolation_threshold = !strcmp(goal,"SI");
goal_is_bond_percolation_threshold = !strcmp(goal,"BO");
goal_is_percolation_threshold =
goal_is_site_percolation_threshold || goal_is_bond_percolation_threshold;
}
// else goal_is_equilibration set to true in SETPARAM.C
#endif
else if ( strstr(line,"model:") == line )
{
m_type = read_alpha_parameter_value(model,models,"model");
model_specified = true;
// Only one of the following three will be true.
model_is_ising = !strcmp(model,"IS");
model_is_q_state_potts = !strcmp(model,"Q-");
}
else if ( strstr(line,"dynamics:") == line )
{
d_type = read_alpha_parameter_value(dynamics, dynamics_types,"dynamics");
dynamics_specified = true;
dynamics_is_metropolis = !strcmp(dynamics,"ME");
dynamics_is_glauber = !strcmp(dynamics,"GL");
dynamics_is_swendsen_wang = !strcmp(dynamics,"SW");
dynamics_is_wolff = !strcmp(dynamics,"WO");
}
#if ALTERNATIVE_SPIN_SELECTIONS
else if ( strstr(line,"spin selection:") == line )
{
ss_type = read_alpha_parameter_value(spin_seln, spin_selns, "spin selections");
spin_seln_specified = true;
spin_seln_is_random = !strcmp(spin_seln,"RA");
spin_seln_is_checkerboard = !strcmp(spin_seln,"CH");
}
#endif
// Read Y/N parameters.
else if ( strstr(line,"absolute magnetization:") == line )
{
absolute_magnetization_requested = read_yn_parameter_value();
absolute_magnetization_specified = true;
}
else if ( strstr(line,"precompute nn sites:") == line )
// Read if nn sites to be precomputed
{
use_precomputed_nn_sites = read_yn_parameter_value();
use_precomputed_nn_sites_specified = true;
}
else if ( strstr(line,"timeslice values:") == line )
// Read if timeslice values to be written to file
{
timeslice_values_requested = read_yn_parameter_value();
timeslice_values_specified = true;
}
else if ( strstr(line,"adjust zero initial magnetization:") == line )
adjust_zero_initial_magnetization = read_yn_parameter_value();
else if ( strstr(line,"second moment:") == line )
// Read if second moment is to be measured.
second_moment_measured = read_yn_parameter_value();
else if ( strstr(line,"autocorrelation:") == line )
// Read if autocorrelation is to be measured.
autocorrelation_measured = read_yn_parameter_value();
else if ( strstr(line,"internal energy:") == line )
// Read if internal energy is to be measured.
internal_energy_measured = read_yn_parameter_value();
else if ( strstr(line,"map file:") == line )
// Read if map file requested.
map_file_requested = read_yn_parameter_value();
else if ( strstr(line,"log values:") == line )
// Read if log values to be calculated.
log_values_requested = read_yn_parameter_value();
else if ( strstr(line,"binder cumulant:") == line )
// Read if Binder cumulant to be measured.;
binder_cumulant_measured = read_yn_parameter_value();
#if false
else if ( strstr(line,"percolation correlation length:") == line )
// Read if percolation correlation length to be measured.
percolation_corr_length_measured = read_yn_parameter_value();
else if ( strstr(line,"thermal correlation length A:") == line )
// Read if thermal correlation length A to be measured.;
thermal_corr_length_a_measured = read_yn_parameter_value();
else if ( strstr(line,"thermal correlation length B:") == line )
// Read if thermal correlation length B to be measured.;
thermal_corr_length_b_measured = read_yn_parameter_value();
#endif
// All other lines ignored.
}
fclose(input_file);
}
/*-------------------------------*/
static void read_lattice_type(void)
{
strcpy(temp,strchr(line,':')+1);
remove_leading_spaces(temp);
memcpy(lattice_type,temp,3);
lattice_type[3] = 0;
_strupr(lattice_type);
if ( !strcmp(lattice_type,"SQ") )
strcpy(lattice_type,"SQU");
for ( l_type=0; l_type<NUM_LATTICE_TYPES; l_type++ )
{
if ( !strcmp(lattice_types[l_type].id,lattice_type) )
break;
}
if ( l_type == NUM_LATTICE_TYPES )
display_input_data_error("lattice type"); // Does not return.
}
/*--------------------------------------------------*/
static int read_numeric_parameter_value(double *param,
double min_value, double max_value, char *param_name)
{
strcpy(temp,strchr(line,':')+1);
remove_leading_spaces(temp);
if ( !*temp )
return ( false );
else
{
*param = atof(temp);
if ( *param < min_value || *param > max_value )
display_input_data_error(param_name); // Does not return.
return ( true );
}
}
/*-----------------------------------------------------------*/
static int read_rational_numeric_parameter_value(double *param,
double min_value, double max_value, char *param_name)
{
int n, d;
strcpy(temp,strchr(line,':')+1);
remove_leading_spaces(temp);
if ( !*temp )
return ( false );
else
{
if ( strchr(temp,'/') == NULL )
*param = atof(temp);
else
{
n = atoi(temp);
d = atoi(1+strchr(temp,'/'));
if ( d == 0 )
return ( false );
*param = (double)n/d;
}
if ( *param < min_value || *param > max_value )
display_input_data_error(param_name); // Does not return.
return ( true );
}
}
/*----------------------------------------------*/
static int read_alpha_parameter_value(char type[],
const char types[][2][30],
char *type_name)
{
int index;
strcpy(temp,strchr(line,':')+1);
remove_leading_spaces(temp);
memcpy(type,temp,2);
type[2] = 0;
_strupr(type);
index = -1;
do {
if ( !types[++index][1][0] )
display_input_data_error(type_name); // Does not return.
} while ( strcmp(types[index][0],type) );
return ( index );
}
//
/*------------------------------------*/
static int read_yn_parameter_value(void)
{
int ch;
strcpy(temp,strchr(line,':')+1);
remove_leading_spaces(temp);
_strupr(temp);
ch = temp[0];
if ( ! ( ch == 'Y' || ch == 'N' || ch == 0 ) )
{
*strchr(line,':') = 0;
display_input_data_error(line); // Does not return.
}
return ( ch == 'Y' );
}