// DISP_LAT.C
// © 2021 Peter J. Meyer
#include <process.h>
#include <math.h>
#include "iss.h"
#define SITE_IN_SPANNING_CLUSTER_2(i,j) ( sites2[i][j] & IN_SPANNING_CLUSTER )
#define SITE_IN_SPANNING_CLUSTER_3(i,j,k) ( sites2[i][j][k] & IN_SPANNING_CLUSTER )
#define SITE_IN_SPANNING_CLUSTER_4(i,j,k,l) ( sites2[i][j][k][l] & IN_SPANNING_CLUSTER )
#define ENABLE_CONTRACTED_MAP true
#define MAX_MAP_DIMENSIONALITY 2
#define I ((3*i)+1)
#undef J
#define J ((3*j)+1)
extern double v_bond_probability;
extern short int w_i, w_j, w_k, w_l;
int print_contracted_map = ENABLE_CONTRACTED_MAP;
static int max_size_for_map[] = { 0, 0, 24, 12, 6 };
// Maximum sizes for maps based on dimensionality.
static char slice[72][78];
static int q_state_potts_spins[MAX_Q_VALUE+1];
static int total_q_state_potts_spins;
static void blank_map_slice(void);
static void zero_potts_spin_counts(void);
static void write_map_slice(FILE *file, int context, int v_bonds);
static void write_2d_map(FILE *file, int context, int v_bonds);
static void write_3d_map(FILE *file, int context, int v_bonds);
static void write_4d_map(FILE *file, int context, int v_bonds);
/*----------------------------*/
void display_map(char *filepath,
int context) // 0 = general purpose
// 1 = display_spanning_path
// 2 = Swendsen-Wang before cluster flip
// 3 = Swendsen-Wang after cluster flip
// 4 = Wolff after cluster flip
{
FILE *map_file;
if ( !open_file(filepath,"wt",&map_file) )
display_file_error_message("open","map",filepath); // Does not return.
if ( dimensionality > MAX_MAP_DIMENSIONALITY )
fprintf(map_file,"\nMap file not currently supported for d>%d.\n",
MAX_MAP_DIMENSIONALITY);
else if ( size > max_size_for_map[dimensionality] )
fprintf(map_file,"\nMaximum size for map of %dd lattice is %d.\n",
dimensionality,max_size_for_map[dimensionality]);
else
{
switch ( dimensionality )
{
case 2:
// Write bonds map.
write_2d_map(map_file,0,false);
if ( context >= 2 )
// Write virtual bonds map.
write_2d_map(map_file,context,true);
break;
case 3:
// write_3d_map(map_file,write_model_info);
break;
case 4:
// write_4d_map(map_file,write_model_info);
break;
}
}
fclose(map_file);
// Call up NotePad (rather than WordPad) to display the map file.
spawnlp(P_NOWAIT,"notepad.exe","notepad.exe",filepath,NULL);
// printf("\nPress a key ... ");
if ( getch() == ESCAPE )
exit(0);
}
/*--------------------------------*/
static void write_2d_map(FILE *file,
int context,
int v_bonds)
{
int i, j, occupied, spin;
unsigned char bonds;
blank_map_slice();
zero_potts_spin_counts();
for ( i=0; i<size; i++ )
{
for ( j=0; j<size; j++ )
{
occupied = spin = spin_at_site(i,j);
if ( occupied )
{
if ( v_bonds )
bonds = v_bonds2[i][j];
else
bonds = bonds2[i][j];
if ( !honeycomb_lattice )
{
if ( bonds & BIT1_0 )
slice[I+1][J] = '|';
// slice[I+1][J] = '0' + (cluster_numbers2[i][j]%10);
if ( bonds & BIT1_1 )
slice[I-1][J] = '|';
if ( bonds & BIT1_2 )
slice[I][J+1] = '-';
if ( bonds & BIT1_3 )
slice[I][J-1] = '-';
if ( bonds & BIT1_4 )
slice[I+1][J+1] = '\\';
if ( bonds & BIT1_5 )
{
slice[I-1][J-1] = '\\';
// Don't print contracted map since
// this would not show these characters.
print_contracted_map = false;
}
if ( bonds & BIT1_6 )
slice[I+1][J-1] = '/';
if ( bonds & BIT1_7 )
{
slice[I-1][J+1] = '/';
print_contracted_map = false;
}
}
else
{
if ( major_axis == 0 )
{
if ( bonds & BIT1_0 )
slice[I+1][J] = '|';
if ( bonds & BIT1_1 )
slice[I-1][J] = '|';
if ( bonds & BIT1_2 )
{
if ( (i+j)%2 )
slice[I][J-1] = '-';
else
slice[I][J+1] = '-';
}
}
else // major_axis = 1
{
if ( bonds & BIT1_0 )
slice[I][J+1] = '-';
if ( bonds & BIT1_1 )
slice[I][J-1] = '-';
if ( bonds & BIT1_2 )
{
if ( (i+j)%2 )
slice[I-1][J] = '|';
else
slice[I+1][J] = '|';
}
}
}
if ( goal_is_percolation_threshold )
{
if ( SITE_IN_SPANNING_CLUSTER_2(i,j) )
slice[I][J] = 'S';
else if ( SITE_IS_VISITED_2(i,j) )
slice[I][J] = 'V';
else
slice[I][J] = 'O';
}
else if ( model_is_ising )
slice[I][J] = ( spin == UP_SPIN ? 'X' : '0' );
else // model is q-state Potts
{
q_state_potts_spins[spin]++;
total_q_state_potts_spins++;
if ( q < 10 )
slice[I][J] = spin + '0';
else
{
slice[I][J] = spin%10 + '0';
if ( spin > 9 )
slice[I][J-1] = spin/10 + '0';
}
}
}
}
}
write_map_slice(file, context, v_bonds);
}
/*------------------------------------*/
static void zero_potts_spin_counts(void)
{
int i;
for ( i=1; i<=q; i++ )
q_state_potts_spins[i] =0;
total_q_state_potts_spins = 0;
}
/*-----------------------------*/
static void blank_map_slice(void)
{
int i, j;
for ( i=0; i<3*size; i++ )
for ( j=0; j<3*size; j++ )
slice[i][j] = SPACE;
// Put dots around the boundaries.
for ( j=0; j<3*size; j++ )
slice[0][j] = '.';
for ( j=1; j<3*size-1; j++ )
slice[3*size-1][j] = '.';
for ( i=1; i<3*size; i++ )
slice[i][0] = slice[i][3*size-1] = ':';
}
/*-----------------------------------*/
static void write_map_slice(FILE *file,
int context,
int v_bonds)
{
int i, j;
double magn, site_pc, bond_pc;
if ( context < 2 )
{
fprintf(file,"\nInput file: %s. Runtime: %s %s",
input_filepath,system_date(temp,0),system_time(temp2,0));
fprintf(file,"\n\nlattice dimensionality/type/size: %dd %s (%d) %d",
dimensionality,lattice_types[l_type].name,
lattice_types[l_type].coord_num,size);
for ( i=2; i<=dimensionality; i++ )
fprintf(file,"x%d",size);
if ( direction_table_is_parity_dependent && MAJOR_AXIS_SPECIFICATION_PERMITTED )
fprintf(file,"\nmajor axis: %d",major_axis);
#if FREE_BOUNDARY_CONDITIONS_POSSIBLE
fprintf(file,"\n%s boundary conditions",
( free_boundary_conditions ? "free" : "periodic" ));
#endif
if ( seed )
fprintf(file," Random seed = %u",seed);
fprintf(file,"\ndynamics: %s",dynamics_types[d_type][1]);
if ( dynamics_is_swendsen_wang || dynamics_is_wolff )
fprintf(file," (p = %.5f)",v_bond_probability);
else
fprintf(file,"\nspin selection: %s",spin_selns[ss_type][1]);
fprintf(file,"\n\nsite concentration = %.6f, bond concentration = %.6f",
site_concentration, bond_concentration);
site_pc = ((double)num_spins*100)/num_sites;
fprintf(file,"\n%s of %s lattice sites occupied (%.2f%%).\n",
ultoa_commas(num_spins,temp),
ultoa_commas(num_sites,temp1),site_pc);
bond_pc = ((double)num_opened_bonds*100)/num_pairs_nn;
fprintf(file,"%s bonds opened (%.2f%% of the %s pairs of nn sites).\n",
ultoa_commas(num_opened_bonds,temp),bond_pc,ultoa_commas(num_pairs_nn,temp2));
}
if ( goal_is_percolation_threshold )
fprintf(file,"\nS = site on spanning path, "
"V = other visited site, O = other occupied site");
else
{
if ( context < 2 )
{
if ( model_is_ising )
fprintf(file,"\nIsing model, ");
else
fprintf(file,"\n%d-state Potts model, ",q);
fprintf(file,"%dd %s lattice",
dimensionality,lattice_types[l_type].name);
if ( direction_table_is_parity_dependent && MAJOR_AXIS_SPECIFICATION_PERMITTED )
fprintf(file,", major axis = %d",major_axis);
fprintf(file,"\ninitial magnetization = %.3f, temperature = %.3f",
initial_magnetization, temperature);
magn = magnetization_per_spin();
fprintf(file,"\nMcs = %-6lu ",mcs_num);
if ( !num_spin_flips_overflow )
fprintf(file,"num_spin_flips = %s",
ultoa_commas((unsigned long)num_spin_flips,temp));
else
fprintf(file,"Number of millions of spin flips = %.0f",
(num_spin_flips + pow(2,32)*num_spin_flips_overflow)/1e6);
fprintf(file,"\nAbs.mag.= %-6d Mag.=%6.3f ",abs_magnetization,magn);
if ( internal_energy_measured )
fprintf(file,"Abs.int.en.= %-6d",abs_internal_energy);
if ( model_is_ising )
fprintf(file,"\nX = up-spin, 0 = down-spin");
else // model is q-state Potts
fprintf(file,"\nspin values: 1 (up) through %d",q);
}
}
fprintf(file,"\n");
if ( context == 2 )
{
if ( v_bonds )
fprintf(file,"Virtual bonds created with probability = %.5f"
" before cluster%s flipped.",v_bond_probability,
( dynamics_is_swendsen_wang ? "s" : "" ));
else
fprintf(file,"Actual bonds before cluster%s flipped.",
( dynamics_is_swendsen_wang ? "s" : "" ));
}
else if ( context == 3 || context == 4 )
{
if ( v_bonds )
fprintf(file,"Virtual bonds after cluster%s flipped.",
( dynamics_is_swendsen_wang ? "s" : "" ));
else
fprintf(file,"Actual bonds after cluster%s flipped.",
( dynamics_is_swendsen_wang ? "s" : "" ));
if ( context == 4 )
fprintf(file,"\nCluster grown from site i=%d,j=%d. Cluster size = %d",
w_i,w_j,ct_size_of_cluster);
if ( dynamics_is_swendsen_wang || dynamics_is_wolff )
{
fprintf(file,"\nnum_clusters_traced_this_sweep = %u",num_clusters_traced_this_sweep);
fprintf(file,"\nnum_spins_visited_this_sweep = %u",num_spins_visited_this_sweep);
fprintf(file,"\nnum_spins_flipped_this_sweep = %u",num_spins_flipped_this_sweep);
write_stack_data(file);
}
}
fprintf(file,"\n\n");
fprintf(file," ");
for ( i=0; i<size; i++ )
fprintf(file,"%2d ",i);
fprintf(file,"\n");
for ( i=0; i<3*size; i++ )
{
if ( print_contracted_map )
{
// Contract vertical double bonds to single bonds
// (if sure that the map is OK). But if there are
// upper diagonal bonds then don't contract the map.
if ( i>0 && !(i%3) )
continue;
}
fprintf(file, "%2s ",( (i+2)%3 ? " " : itoa(i/3,temp,10) ) );
for ( j=0; j<3*size; j++ )
fputc(slice[i][j],file);
fprintf(file, " %-2s",( (i+2)%3 ? " " : itoa(i/3,temp,10) ) );
fputc('\n',file);
}
fprintf(file," ");
for ( i=0; i<size; i++ )
fprintf(file,"%2d ",i);
fprintf(file,"\n");
if ( model_is_q_state_potts && magn < 1.0 )
{
fprintf(file,"\nNumbers of q-state Potts spin values:");
for ( j=0; j<2; j++ )
{
if ( 16*j + 1 > q )
break;
fprintf(file,"\n");
for ( i=16*j; i<16*(j+1); i++ )
{
if ( i + 1 > q )
break;
fprintf(file,"%5d",i+1);
}
if ( q <= 16 || j == 1)
fprintf(file," total");
fprintf(file,"\n");
for ( i=16*j; i<16*(j+1); i++ )
{
if ( i + 1 > q )
break;
fprintf(file,"%5d",q_state_potts_spins[i+1]);
}
}
fprintf(file,"%5d",total_q_state_potts_spins);
}
fprintf(file,"\n");
}
/*--------------------------------*/
static void write_3d_map(FILE *file,
int context,
int v_bonds)
{
}
/*--------------------------------*/
static void write_4d_map(FILE *file,
int context,
int v_bonds)
{
}