// SETPARAM.C // © 2021 Peter J. Meyer #include "iss.h" // Parameters for the simulation are obtained from an input data file. static int get_divisors(void); static int compare_function(const void *arg1, const void *arg2); // All flags are set to false in FLAGS.H. /*---------------------*/ void set_parameters(void) { int i; double crit_temp; #if !DOES_PERCOLATION_THRESHOLDS goal_is_equilibration = goal_specified = true; #endif if ( !goal_specified ) display_missing_data_message("goal"); // Does not return. // goal_is_percolation_threshold is set in READ.C. free_boundary_conditions = goal_is_percolation_threshold; if ( !lattice_type_specified ) display_missing_data_message("lattice type"); // Does not return. dimensionality = lattice_types[l_type].dimensionality; // Set number of dimensions coord_num = lattice_types[l_type].coord_num; // Set coordination number // major axis is 0 by default #if !MAJOR_AXIS_SPECIFICATION_PERMITTED if ( major_axis != 0 ) { printf("\nSpecification of major axis not permitted.\n"); exit(1); } #endif set_direction_table(); // Set directions to nn. set_directionalities(); // Set directionalities for (possible) use // in trace_single_cluster(). if ( !size_specified ) display_missing_data_message("lattice size"); if ( goal_is_percolation_threshold && size < MIN_SIZE_PT ) { printf("\nIn determination of percolation threshold" " the lattice size must be at least %d.\n",MIN_SIZE_PT); exit(1); } if ( size%2 ) { printf("\nLattice size must be divisible by 2.\n"); exit(1); } // Calculate number of sites. num_sites = 1; for ( i=0; i<dimensionality; i++ ) num_sites *= size; // Largest number of sites is 16,777,216 // so no problem with num_sites declared as int. if ( !site_concentration_specified ) site_concentration = 1.0; if ( !bond_concentration_specified ) bond_concentration = 1.0; site_diluted = ( site_concentration < 1.0 ); bond_diluted = ( bond_concentration < 1.0 ); non_diluted = ( !site_diluted && !bond_diluted ); if ( !use_precomputed_nn_sites_specified ) display_missing_data_message("\"precompute nn sites\""); // Does not return. if ( !absolute_magnetization_specified ) display_missing_data_message("\"absolute magnetization\""); if ( !timeslice_values_specified ) display_missing_data_message("\"timeslice values\""); if ( goal_is_percolation_threshold ) { if ( goal_is_site_percolation_threshold ) { if ( site_concentration_specified ) printf("\nsite concentration ignored."); } else if ( goal_is_bond_percolation_threshold ) { if ( bond_concentration_specified ) printf("\nbond concentration ignored."); } if ( !precision_specified ) display_missing_data_message("precision"); // precision specified as number of decimal places. precision = 1.0; for ( i=0; i<num_decimal_places; i++ ) precision /= 10; num_temperatures = 1; // so inner loop works in main() } else // goal is equilibration { standard_deviation_measured = true; if ( !model_specified ) { model_is_ising = true; m_type = 0; } if ( model_is_ising ) spin_value_mask = 1; // 00000001 else { if ( !q_value_specified ) display_missing_data_message("q-value"); // Does not return. spin_value_mask = MAX_Q_VALUE; // decimal 15 = 00001111 } if ( !num_configurations_specified ) num_configurations = 1; if ( !num_spin_assignments_specified ) num_spin_assignments = 1; if ( !num_repetitions_specified ) num_repetitions = 1; if ( !percentage_range_for_mean_specified ) percentage_range_for_mean = 20; // display_missing_data_message("percentage range for mean"); if ( !initial_magnetization_specified ) initial_magnetization = 1.0; if ( model_is_q_state_potts ) { if ( initial_magnetization < -1.0/(q-1) ) display_input_data_error("initial magnetization"); // Does not return. } #if false // Measurement of correlation lengths not done. if ( non_diluted ) { if ( percolation_corr_length_measured ) { printf("\nMeasurement of percolation correlation length" "\nis not appropriate with a non-diluted lattice.\n"); exit(1); } } #endif if ( num_temperatures == 0 ) display_missing_data_message("temperature"); single_temperature_specified = ( num_temperatures == 1 ); multiple_temperatures_specified = !single_temperature_specified; for ( i=0; i<num_temperatures; i++ ) { if ( temperatur[i] == -1 ) { // Critical temperature requested. if ( ( crit_temp = get_critical_temperature() ) == -1 ) { sprintf(temp,models[m_type][1],q); printf("\nCannot ascertain critical temperature for %dd %s model.\n", dimensionality,temp); exit(1); } temperatur[i] = crit_temp; } else if ( temperatur[i] == 0.0 ) { printf("\nCannot perform equilibration for zero temperature.\n"); exit(1); } } if ( multiple_temperatures_specified ) // Sort temperatures. qsort(temperatur,num_temperatures,sizeof(double),compare_function); else temperature = temperatur[0]; if ( !dynamics_specified ) display_missing_data_message("dynamics"); if ( size > max_size[d_type][dimensionality] ) { printf("\nMaximum size for a %dd lattice with %s dynamics is %d.\n", dimensionality,dynamics_types[d_type][1],max_size[d_type][dimensionality]); exit(1); } if ( dynamics_is_metropolis || dynamics_is_glauber ) { // Transition probabilities are calculated // in perform_equilibration() in EQUIL.C. if ( !spin_seln_specified || !ALTERNATIVE_SPIN_SELECTIONS ) { spin_seln_is_checkerboard = true; ss_type = 0; } if ( spin_seln_is_checkerboard ) num_divisors = get_divisors(); } if ( non_diluted && num_configurations > 1 ) { printf("\nInconsistent data input: Input data file specifies" "\na non-diluted lattice with more than one configuration.\n"); exit(1); } if ( !num_time_slices_specified ) display_missing_data_message("number of time slices"); if ( !step_length_specified ) display_missing_data_message("step length"); if ( initial_magnetization == 1.0 && autocorrelation_measured ) { printf("\nWith initial magnetization = 1 the autocorrelation values" "\nare the same as the magnetization values.\n"); } if ( absolute_magnetization_requested && initial_magnetization < 0 ) { printf("\nAbsolute magnetization values are requested" "\nbut the initial magnetization is negative: %f\n",initial_magnetization); exit(1); } #if false // Set site percolation threshold. site_perc_thr = lattice_types[l_type].site_perc_thr; // Set bond percolation threshold. bond_perc_thr = lattice_types[l_type].bond_perc_thr; #endif } } /*-------------------------*/ static int get_divisors(void) { // First get all factors d of size such that 2 <= d <= size/2. int i=0, j, d=2; do { if ( !(size%d) ) divisors[i++] = d; d++; } while ( i < MAX_DIVISORS && d <= size/2 ); // If i > 7 reduce the number of divisors until it is 6 or 7. while ( i > 7 ) { for ( j=1; j<i-1; j++ ) divisors[j-1] = divisors[j]; i -= 2; } return ( i ); } /*----------------------------------------------------------*/ static int compare_function(const void *arg1, const void *arg2) { double x1 = *(double *)arg1; double x2 = *(double *)arg2; if ( x1 < x2 ) return ( -1 ); else if ( x1 > x2 ) return ( 1 ); else return ( 0 ); }