// 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' ); }