// ALLOC.C
// Allocation of memory for arrays
// © 2021 Peter J. Meyer
#include "iss.h"
/*----------------------*/
void allocate_arrays(void)
{
int err_flag;
unsigned int memory_for_arrays=0;
unsigned int memory_for_precomputed_sites;
if ( dimensionality > MAX_DIMENSIONALITY )
{
printf("\nA %dd spin model is not currently supported.\n",dimensionality);
exit(101);
}
printf("\nMemory for ");
switch ( dimensionality )
{
case 2:
// Allocate a 2-dimensional array to hold the sites information.
sites2 = (A2(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(0,err_flag); // Does not return.
printf("sites2");
memory_for_arrays += num_sites;
// num_sites has been set in SETPARAM.C.
// Allocate a 2-dimensional array to hold the bonds information.
bonds2 = (A2(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(1,err_flag);
memory_for_arrays += num_sites;
printf(", bonds2");
if ( dynamics_is_swendsen_wang || dynamics_is_wolff )
{
// Allocate a 2-dimensional array to hold the virtual bonds information.
v_bonds2 = (A2(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(2,err_flag);
memory_for_arrays += num_sites;
printf(", v_bonds2");
}
if ( use_precomputed_nn_sites )
{
precomp_nn_sites2 = (A4(short int))array_alloc(&err_flag, sizeof(short int),
NULL, 4, size, size, MAX_COORD_NUM, MAX_DIMENSIONALITY);
if ( err_flag )
display_array_allocation_error(6,err_flag);
memory_for_precomputed_sites = num_sites*MAX_COORD_NUM*MAX_DIMENSIONALITY*sizeof(short int);
memory_for_arrays += memory_for_precomputed_sites;
printf(", precomp_nn_sites2 (%s KB),\n",
ultoa_commas((unsigned long)memory_for_precomputed_sites/1024,temp));
}
if ( autocorrelation_measured || num_repetitions > 1 )
{
// Allocate a 2-dimensional array to hold the initial spin assignments.
initial_sites2 = (A2(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(3,err_flag);
memory_for_arrays += num_sites;
if ( !use_precomputed_nn_sites )
printf(", ");
printf("initial_sites2");
}
#if false
if ( thermal_corr_length_b_measured )
{
// Allocate a 2-dimensional array to hold the shifted spin assignments.
shifted_sites2 = (A2(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(3,err_flag);
memory_for_arrays += num_sites;
printf(", initial_sites2");
}
#endif
#if false
// Measurement of correlation lengths not done.
if ( percolation_corr_length_measured || thermal_corr_length_a_measured )
{
// Allocate a 2-dimensional array to hold cluster number for each spin.
cluster_numbers2 = (A2(unsigned short int))array_alloc(&err_flag,
sizeof(unsigned short int), NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(4,err_flag);
memory_for_arrays += num_sites*sizeof(unsigned short int);
printf(", cluster_numbers2");
#if RECORD_SPIN_DISTANCES
// Allocate a 2-dimensional array to hold spin distances in cluster trace.
spin_distances2 = (A2(unsigned short int))array_alloc(&err_flag,
sizeof(unsigned short int), NULL, 2, size, size);
if ( err_flag )
display_array_allocation_error(5,err_flag);
memory_for_arrays += num_sites*sizeof(unsigned short int);
printf(", spin_distances2");
#endif
}
#endif
break;
case 3:
// Allocate a 3-dimensional array to hold the sites information.
sites3 = (A3(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 3, size, size, size);
if ( err_flag )
display_array_allocation_error(0,err_flag); // Does not return.
memory_for_arrays += num_sites;
printf("sites3");
// Allocate a 3-dimensional array to hold the bonds information.
bonds3 = (A3(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 3, size, size, size);
if ( err_flag )
display_array_allocation_error(1,err_flag);
memory_for_arrays += num_sites;
printf(", bonds3");
if ( dynamics_is_swendsen_wang || dynamics_is_wolff )
{
// Allocate a 3-dimensional array to hold the virtual bonds information.
v_bonds3 = (A3(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 3, size, size, size);
if ( err_flag )
display_array_allocation_error(2,err_flag);
memory_for_arrays += num_sites;
printf(", v_bonds3");
}
if ( use_precomputed_nn_sites )
{
precomp_nn_sites3 = (A5(short int))array_alloc(&err_flag, sizeof(short int),
NULL, 5, size, size, size, MAX_COORD_NUM, MAX_DIMENSIONALITY);
if ( err_flag )
display_array_allocation_error(6,err_flag);
memory_for_precomputed_sites = num_sites*MAX_COORD_NUM*MAX_DIMENSIONALITY*sizeof(short int);
memory_for_arrays += memory_for_precomputed_sites;
printf(", precomp_nn_sites3 (%s KB),\n",
ultoa_commas((unsigned long)memory_for_precomputed_sites/1024,temp));
}
if ( autocorrelation_measured || num_repetitions > 1 )
{
// Allocate a 3-dimensional array to hold the initial spin assignments.
initial_sites3 = (A3(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 3, size, size, size);
if ( err_flag )
display_array_allocation_error(3,err_flag);
memory_for_arrays += num_sites;
if ( !use_precomputed_nn_sites )
printf(", ");
printf("initial_sites3");
}
#if false
if ( percolation_corr_length_measured || thermal_corr_length_a_measured )
;
#endif
break;
case 4:
// Allocate a 4-dimensional array to hold the sites information.
sites4 = (A4(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 4, size, size, size, size);
if ( err_flag )
display_array_allocation_error(0,err_flag); // Does not return.
memory_for_arrays += num_sites;
printf("sites4");
// Allocate a 4-dimensional array to hold the bonds information.
bonds4 = (A4(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 4, size, size, size, size);
if ( err_flag )
display_array_allocation_error(1,err_flag);
memory_for_arrays += num_sites;
printf(", bonds4");
if ( dynamics_is_swendsen_wang || dynamics_is_wolff )
{
// Allocate a 4-dimensional array to hold the virtual bonds information.
v_bonds4 = (A4(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 4, size, size, size, size);
if ( err_flag )
display_array_allocation_error(2,err_flag);
memory_for_arrays += num_sites;
printf(", v_bonds4");
}
if ( use_precomputed_nn_sites )
{
precomp_nn_sites4 = (A6(short int))array_alloc(&err_flag, sizeof(short int),
NULL, 6, size, size, size, size, MAX_COORD_NUM, MAX_DIMENSIONALITY);
if ( err_flag )
display_array_allocation_error(6,err_flag);
memory_for_precomputed_sites = num_sites*MAX_COORD_NUM*MAX_DIMENSIONALITY*sizeof(short int);
memory_for_arrays += memory_for_precomputed_sites;
printf(", precomp_nn_sites4 (%s KB),\n",
ultoa_commas((unsigned long)memory_for_precomputed_sites/1024,temp));
}
if ( autocorrelation_measured || num_repetitions > 1 )
{
// Allocate a 4-dimensional array to hold the initial spin assignments.
initial_sites4 = (A4(unsigned char))array_alloc(&err_flag, sizeof(char),
NULL, 4, size, size, size, size);
if ( err_flag )
display_array_allocation_error(3,err_flag);
memory_for_arrays += num_sites;
if ( !use_precomputed_nn_sites )
printf(", ");
printf("initial_sites4");
}
#if false
if ( percolation_corr_length_measured || thermal_corr_length_a_measured )
;
#endif
break;
}
fflush(stdout);
if ( goal_is_equilibration )
{
// Allocate a 2d array of doubles for sum of the magnetization
// the sum of the square of the magnetization at each time slice,
// and allocate space for the second moment values.
magnetization = (A2(double))array_alloc(&err_flag,
sizeof(double), NULL, 2, num_time_slices+1,
NUM_MAGNETIZATION_COMPONENTS); // See ISM_DEF.H
if ( err_flag )
{
printf("\nError %d when allocating array for magnetizations.\n",err_flag);
exit(1);
}
memory_for_arrays += sizeof(double)*(num_time_slices+1)*NUM_MAGNETIZATION_COMPONENTS;
if ( internal_energy_measured )
{
// Allocate a 2d array of doubles for sum of the internal energy
// and the sum of the square of the internal energy at each time slice.
internal_energy = (A2(double))array_alloc(&err_flag,
sizeof(double), NULL, 2, num_time_slices+1,
NUM_INTERNAL_ENERGY_COMPONENTS);
if ( err_flag )
{
printf("\nError %d when allocating array for internal energies.\n",err_flag);
exit(1);
}
memory_for_arrays += sizeof(double) * (num_time_slices+1)
* NUM_INTERNAL_ENERGY_COMPONENTS;
}
if ( second_moment_measured && model_is_q_state_potts )
{
// Allocate a 2d array of doubles for squares of magnetizations.
potts_magnetization_squares = (A2(double))array_alloc(&err_flag,
sizeof(double), NULL, 2, num_time_slices+1, q+1);
if ( err_flag )
{
printf("\nError %d when allocating array for "
"squares of potts magnetizations.\n",err_flag);
exit(1);
}
memory_for_arrays += sizeof(double) * (num_time_slices+1)*(q+1);
}
if ( autocorrelation_measured )
{
// Allocate a 2d array of doubles for sum of the autocorrelations
// and the squares of the autocorrelations.
autocorrelation = (A2(double))array_alloc(&err_flag,
sizeof(double), NULL, 2, num_time_slices+1,
NUM_AUTOCORRELATION_COMPONENTS);
if ( err_flag )
{
printf("\nError %d when allocating array for autocorrelation.\n",err_flag);
exit(1);
}
memory_for_arrays += sizeof(double) * (num_time_slices+1)
* NUM_AUTOCORRELATION_COMPONENTS;
}
}
fflush(stdout);
// Allocate a 2d array of MAX_DIMENSIONALITY x size chars (used in CLUSTERS.C).
edge = (A2(char))array_alloc(&err_flag, sizeof(char), NULL, 2, MAX_DIMENSIONALITY, size);
if ( err_flag )
{
printf("\nError %d when allocating edge[][] array.\n",err_flag);
exit(1);
}
memory_for_arrays += sizeof(char)*MAX_DIMENSIONALITY*size;
printf(" and other arrays:");
if ( memory_for_arrays < 10000 )
printf(" %d bytes",memory_for_arrays);
else
{
ultoa_commas(memory_for_arrays/1024,temp);
printf(" %s KB",temp);
}
if ( goal_is_percolation_threshold || dynamics_is_swendsen_wang || dynamics_is_wolff
|| percolation_corr_length_measured || thermal_corr_length_measured )
{
if ( dynamics_is_swendsen_wang )
stack_size = SHORT_INTS_PER_SWENDSEN_WANG_STACK_PUSH;
else if ( dynamics_is_wolff )
stack_size = SHORT_INTS_PER_WOLFF_STACK_PUSH;
else
stack_size = dimensionality;
stack_size = stack_size*num_sites + size;
// Maximum number of ints the stack can hold.
allocate_memory_for_stack(); // STACK.C
ultoa_commas(stack_size,temp);
printf("\nPlus memory for stack of up to %s short ints: ",temp);
if ( stack_size*sizeof(short int) < 10000 )
{
ultoa_commas(stack_size*sizeof(short int),temp);
printf(" %s bytes",temp);
}
else
{
ultoa_commas((stack_size*sizeof(short int))/1024,temp);
printf(" %s KB",temp);
}
memory_for_arrays += stack_size*sizeof(short int);
}
else
stack_size = 0;
printf("\nTotal memory allocated:");
if ( memory_for_arrays < 10000 )
printf(" %d bytes",memory_for_arrays);
else
{
ultoa_commas(memory_for_arrays/1024,temp);
printf(" %s KB",temp);
}
printf("\n");
fflush(stdout);
}
/*------------------*/
void free_arrays(void)
{
switch ( dimensionality )
{
case 2:
// Free the array holding the sites information.
if ( !array_free(sites2, 2) )
display_array_free_error(0);
// Free the array holding the bonds information.
if ( !array_free(bonds2, 2) )
display_array_free_error(1);
if ( dynamics_is_swendsen_wang )
{
// Free the array holding the v_bonds information.
if ( !array_free(v_bonds2, 2) )
display_array_free_error(2);
}
if ( autocorrelation_measured )
{
// Free the array holding the initial_sites information.
if ( !array_free(initial_sites2, 2) )
display_array_free_error(3);
}
break;
case 3:
// Free the array holding the sites information.
if ( !array_free(sites3, 3) )
display_array_free_error(0);
// Free the array holding the bonds information.
if ( !array_free(bonds3, 3) )
display_array_free_error(1);
if ( dynamics_is_swendsen_wang )
{
// Free the array holding the v_bonds information.
if ( !array_free(v_bonds3, 3) )
display_array_free_error(2);
}
if ( autocorrelation_measured )
{
// Free the array holding the initial_sites information.
if ( !array_free(initial_sites3, 3) )
display_array_free_error(3);
}
break;
case 4:
// Free the array holding the sites information.
if ( !array_free(sites4, 4) )
display_array_free_error(0);
// Free the array holding the bonds information.
if ( !array_free(bonds4, 4) )
display_array_free_error(1);
if ( dynamics_is_swendsen_wang )
{
// Free the array holding the v_bonds information.
if ( !array_free(v_bonds4, 4) )
display_array_free_error(2);
}
if ( autocorrelation_measured )
{
// Free the array holding the initial_sites information.
if ( !array_free(initial_sites4, 4) )
display_array_free_error(3);
}
break;
}
if ( goal_is_equilibration )
{
if ( !array_free(magnetization,2) )
printf("\nError when freeing array for magnetizations.\n");
if ( second_moment_measured && model_is_q_state_potts )
{
if ( !array_free(potts_magnetization_squares,2) )
printf("\nError when freeing array for potts magnetization squares.\n");
}
if ( autocorrelation_measured )
{
if ( !array_free(autocorrelation,2) )
printf("\nError when freeing array for autocorrelation.\n");
}
}
if ( stack_size != 0 )
if ( !array_free(stack,1) )
printf("\nError when freeing array for stack.\n");
}