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