// Q&A.C // Questions and answers // © 2021 Peter J. Meyer #include "iss.h" unsigned int num_times_get_nn_sites_called = 0; unsigned int num_times_get_nn_site_in_dir_called = 0; unsigned int num_times_adjust_index_called = 0; static int adjust_index(short int *ip); // What are the nearest neighbour sites of a given site // (whether or not occupied and whether or not an open bond exists)? // // For a given site (i,j,..), nn_sites[r][n] is index n of the nearest neighbour // site in direction r (where 0 <= n < dimensionality). // If periodic boundary conditions are used, or the site is not a boundary site, // then the number of nn sites equals the coordination number. // If free boundary conditions are used and the site is a boundary site // then nn_sites[r][0] will be NON_EXISTENT for some r. // This function does not check which nearest neighbour sites // are occupied or whether open bonds to them exist. /*--------------------------------*/ void get_nn_sites(int i, int j, ...) { int k, l, r, index, boundary_site; num_times_get_nn_sites_called++; if ( use_precomputed_nn_sites ) { switch ( dimensionality ) { case 2: for ( r=0; r<coord_num; r++ ) for ( index=0; index<dimensionality; index++ ) nn_sites[r][index] = precomp_nn_sites2[i][j][r][index]; break; case 3: k = *(((int *)(&j))+1); for ( r=0; r<coord_num; r++ ) for ( index=0; index<dimensionality; index++ ) nn_sites[r][index] = precomp_nn_sites3[i][j][k][r][index]; break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); for ( r=0; r<coord_num; r++ ) for ( index=0; index<dimensionality; index++ ) nn_sites[r][index] = precomp_nn_sites4[i][j][k][l][r][index]; break; } } else { switch ( dimensionality ) { case 2: if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j)%2); for ( r=0; r<coord_num; r++ ) // For each direction { nn_sites[r][0] = i + dir[r][0]; // See DIRTABLE.C nn_sites[r][1] = j + dir[r][1]; } boundary_site = IS_BOUNDARY_SITE_2(i,j); break; case 3: k = *(((int *)(&j))+1); if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j+k)%2); for ( r=0; r<coord_num; r++ ) { nn_sites[r][0] = i + dir[r][0]; nn_sites[r][1] = j + dir[r][1]; nn_sites[r][2] = k + dir[r][2]; } boundary_site = IS_BOUNDARY_SITE_3(i,j,k); break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j+k+l)%2); for ( r=0; r<coord_num; r++ ) { nn_sites[r][0] = i + dir[r][0]; nn_sites[r][1] = j + dir[r][1]; nn_sites[r][2] = k + dir[r][2]; nn_sites[r][3] = l + dir[r][3]; } boundary_site = IS_BOUNDARY_SITE_4(i,j,k,l); break; } if ( boundary_site ) { // size -> 0 and -1 -> size-1 for ( r=0; r<coord_num; r++ ) { for ( index=0; index<dimensionality; index++ ) { #if FREE_BOUNDARY_CONDITIONS_POSSIBLE if ( adjust_index(&nn_sites[r][index]) ) // Returns true if index was adjusted, i.e. if index was out of bounds. { if ( free_boundary_conditions ) // No longer occurs { nn_sites[r][0] = NON_EXISTENT; // Meaning that there is no nn in direction r. break; } } #else adjust_index(&nn_sites[r][index]); // With periodic boundary conditions there are no non-existent nn's // so no need to check return value. #endif } } } } } // This assumes that the maximum distance in any direction // of a nearest neighbour is not greater than the lattice size. /*----------------------------------*/ static int adjust_index(short int *ip) { num_times_adjust_index_called++; if ( *ip < 0 ) { *ip += size; return ( true ); } else if ( *ip >= size ) { *ip -= size; return ( true ); } else return ( false ); } // What is the nearest neighbour site of a given site in a given direction? // Returns true if site exists, false otherwise. /*--------------------------------------------*/ int get_nn_site_in_dir(int r, int i, int j, ...) { int k, l, index, boundary_site; int exists = true; num_times_get_nn_site_in_dir_called++; if ( use_precomputed_nn_sites ) { switch ( dimensionality ) { case 2: for ( index=0; index<dimensionality; index++ ) nn_site[index] = precomp_nn_sites2[i][j][r][index]; exists = ( nn_site[0] != NON_EXISTENT ); break; case 3: k = *(((int *)(&j))+1); for ( index=0; index<dimensionality; index++ ) nn_site[index] = precomp_nn_sites3[i][j][k][r][index]; exists = ( nn_site[0] != NON_EXISTENT ); break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); for ( index=0; index<dimensionality; index++ ) nn_site[index] = precomp_nn_sites4[i][j][k][l][r][index]; exists = ( nn_site[0] != NON_EXISTENT ); break; } } else { switch ( dimensionality ) { case 2: if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j)%2); nn_site[0] = i + dir[r][0]; // See DIRTABLE.C nn_site[1] = j + dir[r][1]; boundary_site = IS_BOUNDARY_SITE_2(i,j); break; case 3: k = *(((int *)(&j))+1); if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j+k)%2); nn_site[0] = i + dir[r][0]; nn_site[1] = j + dir[r][1]; nn_site[2] = k + dir[r][2]; boundary_site = IS_BOUNDARY_SITE_3(i,j,k); break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); if ( direction_table_is_parity_dependent ) adjust_direction_table((i+j+k+l)%2); nn_site[0] = i + dir[r][0]; nn_site[1] = j + dir[r][1]; nn_site[2] = k + dir[r][2]; nn_site[3] = l + dir[r][3]; boundary_site = IS_BOUNDARY_SITE_4(i,j,k,l); break; } if ( boundary_site ) { // size -> 0 and -1 -> size-1 for ( index=0; index<dimensionality; index++ ) { #if FREE_BOUNDARY_CONDITIONS_POSSIBLE if ( adjust_index(&nn_site[index]) ) // Returns true if index was adjusted, i.e. if index was out of bounds. { if ( free_boundary_conditions ) { nn_site[0] = NON_EXISTENT; // Meaning that there is no nn in direction r. exists = false; break; } } #else adjust_index(&nn_site[index]); // With periodic boundary conditions there are no non-existent nn's // so no need to check return value. #endif } } } return ( exists ); } #if false // What is the site at a distance n from a given site // in a given direction? // Returns true if site exists, false otherwise. // THIS FUNCTION NEEDS RE-THINKING. /*---------------------------------------------------------------*/ int get_nn_site_at_distance_in_dir(int n, int r, int i, int j, ...) { int k, l, index, boundary_site; int exists = true; switch ( dimensionality ) { case 2: nn_site[0] = i; nn_site[1] = j; while ( n-- ) { if ( direction_table_is_parity_dependent ) adjust_direction_table((nn_site[0]+nn_site[1])%2); // ??? nn_site[0] += dir[r][0]; // See DIRTABLE.C nn_site[1] += dir[r][1]; } boundary_site = IS_BOUNDARY_SITE_2(i,j); break; case 3: k = *(((int *)(&j))+1); nn_site[0] = i; nn_site[1] = j; nn_site[2] = k; while ( n-- ) { if ( direction_table_is_parity_dependent ) adjust_direction_table((nn_site[0]+nn_site[1]+nn_site[2])%2); nn_site[0] += dir[r][0]; nn_site[1] += dir[r][1]; nn_site[2] += dir[r][2]; } boundary_site = IS_BOUNDARY_SITE_3(i,j,k); break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); nn_site[0] = i; nn_site[1] = j; nn_site[2] = k; nn_site[3] = l; while ( n-- ) { if ( direction_table_is_parity_dependent ) adjust_direction_table((nn_site[0]+nn_site[1]+nn_site[2]+nn_site[3])%2); nn_site[0] += dir[r][0]; nn_site[1] += dir[r][1]; nn_site[2] += dir[r][2]; nn_site[3] += dir[r][3]; } boundary_site = IS_BOUNDARY_SITE_4(i,j,k,l); break; } if ( boundary_site ) { // size -> 0 and -1 -> size-1 for ( index=0; index<dimensionality; index++ ) { #if FREE_BOUNDARY_CONDITIONS_POSSIBLE if ( adjust_index(&nn_site[index]) ) // Returns true if index was adjusted, i.e. if index was out of bounds. { if ( free_boundary_conditions ) { nn_site[0] = NON_EXISTENT; // Meaning that there is no nn in direction r. exists = false; break; } } #else adjust_index(&nn_site[index]); // With periodic boundary conditions there are no non-existent nn's // so no need to check return value. #endif } } return ( exists ); } #endif