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