// DIRTABLE.C
// © 2021 Peter J. Meyer
#include "iss.h"
static int inverse_dir[MAX_DIMENSIONALITY];
// Set the values of the direction table based on the type of lattice.
// For direction r, where 0 <= r < coord_num.
// dir[r][n] is the value to add to index n of a given site
// to get index n of the nearest neighbour in direction r.
/*--------------------------*/
void set_direction_table(void)
{
if ( square_lattice )
{ // 0 1 |1
dir[0][0] = 1; dir[0][1] = 0; // 0: +1 0 |
dir[1][0] = -1; dir[1][1] = 0; // 1: -1 0 ---O--->j
dir[2][0] = 0; dir[2][1] = 1; // 2: 0 +1 3 | 2
dir[3][0] = 0; dir[3][1] = -1; // 3: 0 -1 |0
// Vi
}
else if ( triangular_lattice )
{ // 0 1
dir[0][0] = 1; dir[0][1] = 0; // 0: +1 0 5\ |1
dir[1][0] = -1; dir[1][1] = 0; // 1: -1 0 \|
dir[2][0] = 0; dir[2][1] = 1; // 2: 0 +1 --- O --->j
dir[3][0] = 0; dir[3][1] = -1; // 3: 0 -1 3 |\ 2
dir[4][0] = 1; dir[4][1] = 1; // 4: +1 +1 |0\4
dir[5][0] = -1; dir[5][1] = -1; // 5: -1 -1 Vi
}
else if ( double_triangular_lattice )
{ // 0 1
dir[0][0] = 1; dir[0][1] = 0; // 0: +1 0 1
dir[1][0] = -1; dir[1][1] = 0; // 1: -1 0 5\ | /7
dir[2][0] = 0; dir[2][1] = 1; // 2: 0 +1 \|/
dir[3][0] = 0; dir[3][1] = -1; // 3: 0 -1 3---O--->j
dir[4][0] = 1; dir[4][1] = 1; // 4: +1 +1 /|\ 2
dir[5][0] = -1; dir[5][1] = -1; // 5: -1 -1 6/ |0\4
dir[6][0] = 1; dir[6][1] = -1; // 6: +1 -1 Vi
dir[7][0] = -1; dir[7][1] = 1; // 7: -1 +1
}
else if ( honeycomb_lattice )
{
// There are two varieties of honeycomb lattice.
// (But may not need to distinguish between them.)
if ( major_axis == 0 )
{
// 0 1
dir[0][0] = 1; dir[0][1] = 0; // 0: +1 0
dir[1][0] = -1; dir[1][1] = 0; // 1: -1 0
dir[2][0] = 0; dir[2][1] = 1; // 2: 0 +1
}
else // major_axis == 1
{
dir[0][0] = 0; dir[0][1] = 1; // 0: 0 +1
dir[1][0] = 0; dir[1][1] = -1; // 1: 0 -1
dir[2][0] = 1; dir[2][1] = 0; // 2: +1 0
}
// The third direction changes according to whether the site is odd or even.
//
// If the major axis is 0 then the directions are:
//
// 1| 1|
// | |
// O--->j if site even ----0 if site odd
// | 2 2 |
// |0 |0
// Vi Vi
//
// If the major axis is 1 then the directions are:
//
// 2|
// |
// ---O--->j if site even ---0--->j if site odd
// 1 | 0 1 0
// |2
// Vi
//
// If periodic boundary conditions are used then the size
// of the lattice in each dimension must be even.
}
else if ( cubic_lattice )
{ // 0 1 2 1
dir[0][0] = 1; dir[0][1] = 0; dir[0][2] = 0; // 0: +1 0 0 | /3
dir[1][0] = -1; dir[1][1] = 0; dir[1][2] = 0; // 1: -1 0 0 5 |/
dir[2][0] = 0; dir[2][1] = 1; dir[2][2] = 0; // 2: 0 +1 0 ----O--->k
dir[3][0] = 0; dir[3][1] = -1; dir[3][2] = 0; // 3: 0 -1 0 /| 4
dir[4][0] = 0; dir[4][1] = 0; dir[4][2] = 1; // 4: 0 0 +1 2/ |0
dir[5][0] = 0; dir[5][1] = 0; dir[5][2] = -1; // 5: 0 0 -1 jL Vi
}
else if ( quadrilateral_lattice )
{
// Same as cubic with two extra directions.
// 0 1 2 7 1 3
dir[0][0] = 1; dir[0][1] = 0; dir[0][2] = 0; // 0: +1 0 0 \ | /
dir[1][0] = -1; dir[1][1] = 0; dir[1][2] = 0; // 1: -1 0 0 5 \|/
dir[2][0] = 0; dir[2][1] = 1; dir[2][2] = 0; // 2: 0 +1 0 ----O--->k
dir[3][0] = 0; dir[3][1] = -1; dir[3][2] = 0; // 3: 0 -1 0 /|\ 4
dir[4][0] = 0; dir[4][1] = 0; dir[4][2] = 1; // 4: 0 0 +1 2/ |0\6
dir[5][0] = 0; dir[5][1] = 0; dir[5][2] = -1; // 5: 0 0 -1 jL Vi ijk
dir[6][0] = 1; dir[6][1] = 1; dir[6][2] = 1; // 6: +1 +1 +1
dir[7][0] = -1; dir[7][1] = -1; dir[7][2] = -1; // 7: -1 -1 -1
}
else if ( tetrahedral_lattice )
{
#if !TETRAHEDRAL_LATTICE_IMPLEMENTED
printf("\nTetrahedral lattice type not currently supported."
"\nSee DIRTABLE.C\n");
exit(1);
#else
// This is the cubic lattice plus six diagonal bonds.
// Coordination number of 12, so requires bonds array to be >= short ints.
// 0 1 2
dir[0][0] = 1; dir[0][1] = 0; dir[0][2] = 0; // 0: +1 0 0
dir[1][0] = -1; dir[1][1] = 0; dir[1][2] = 0; // 1: -1 0 0
dir[2][0] = 0; dir[2][1] = 1; dir[2][2] = 0; // 2: 0 +1 0
dir[3][0] = 0; dir[3][1] = -1; dir[3][2] = 0; // 3: 0 -1 0
dir[4][0] = 0; dir[4][1] = 0; dir[4][2] = 1; // 4: 0 0 +1
dir[5][0] = 0; dir[5][1] = 0; dir[5][2] = -1; // 5: 0 0 -1
dir[6][0] = 1; dir[0][1] = -1; dir[0][2] = 0; // 6: +1 -1 0
dir[7][0] = -1; dir[1][1] = 1; dir[1][2] = 0; // 7: -1 +1 0
dir[8][0] = 1; dir[2][1] = 0; dir[2][2] = -1; // 8: +1 0 -1
dir[9][0] = -1; dir[3][1] = 0; dir[3][2] = 1; // 9: -1 0 +1
dir[10][0] = 0; dir[4][1] = 1; dir[4][2] = -1; // 10: 0 +1 -1
dir[11][0] = 0; dir[5][1] = -1; dir[5][2] = 1; // 11: 0 -1 +1
#endif
}
else if ( diamond_lattice )
{
// There are three varieties of diamond lattice: major axis = 0, 1 and 2.
// Diamond lattices with major axis 1 and 2 are equivalent, so we need
// consider only two varieties.
if ( major_axis == 0 )
{
// 0 1 2
dir[0][0] = 1; dir[0][1] = 0; dir[0][2] = 0; // 0: +1 0 0
dir[1][0] = -1; dir[1][1] = 0; dir[1][2] = 0; // 1: -1 0 0
dir[2][0] = 0; dir[2][1] = 1; dir[2][2] = 0; // 2: 0 +1 0
dir[3][0] = 0; dir[3][1] = 0; dir[3][2] = 1; // 3: 0 0 +1
}
else // assume major_axis is 1
{
// 0 1 2
dir[0][0] = 0; dir[0][1] = 1; dir[0][2] = 0; // 0: 0 +1 0
dir[1][0] = 0; dir[1][1] = -1; dir[1][2] = 0; // 1: 0 -1 0
dir[2][0] = 1; dir[2][1] = 0; dir[2][2] = 0; // 2: +1 0 0
dir[3][0] = 0; dir[3][1] = 0; dir[3][2] = 1; // 3: 0 0 +1
}
// The last two directions change sign according to
// whether the site is odd or even.
//
// If the major axis is 0 then the directions are:
//
// 1| 1|
// | | /2
// | |/
// O--->k if site even ----0 if site odd
// /| 3 3 |
// 2/ |0 |0
// L | |
// j Vi Vi
//
//
// If the major axis is 1 then the directions are:
//
// /1 2| /1
// / |/
// O--->k if site even 3---0 if site odd
// /| 3 /
// 0/ |2 0/
// L | L
// j Vi j
//
// If periodic boundary conditions are used then the size
// of the lattice in each dimension must be even.
}
else if ( hypercubic_lattice_4d )
{ // 0 1 2 3
dir[0][0]= 1; dir[0][1]= dir[0][2]= dir[0][3] = 0; // 0: +1 0 0 0
dir[1][0]=-1; dir[1][1]= dir[1][2]= dir[1][3] = 0; // 1: -1 0 0 0
dir[2][0]= 0; dir[2][1]= 1; dir[2][2]= dir[2][3]= 0; // 2: 0 +1 0 0
dir[3][0]= 0; dir[3][1]=-1; dir[3][2]= dir[3][3]= 0; // 3: 0 -1 0 0
dir[4][0]= dir[4][1]= 0; dir[4][2]= 1; dir[4][3]= 0; // 4: 0 0 +1 0
dir[5][0]= dir[5][1]= 0; dir[5][2]=-1; dir[5][3]= 0; // 5: 0 0 -1 0
dir[6][0]= dir[6][1]= dir[6][2]= 0; dir[6][3]= 1; // 6: 0 0 0 +1
dir[7][0]= dir[7][1]= dir[7][2]= 0; dir[7][3]=-1; // 7: 0 0 0 -1
}
else if ( hyperdiamond_lattice_4d )
{ // 0 1 2 3
dir[0][0]= 1; dir[0][1]= dir[0][2]= dir[0][3] = 0; // 0: +1 0 0 0
dir[1][0]=-1; dir[1][1]= dir[1][2]= dir[1][3] = 0; // 1: -1 0 0 0
dir[2][0]= 0; dir[2][1]= 1; dir[2][2]= dir[2][3]= 0; // 2: 0 +1 0 0
dir[3][0]= dir[3][1]= 0; dir[3][2]= 1; dir[3][3]= 0; // 3: 0 0 +1 0
dir[4][0]= dir[4][1]= dir[4][2]= 0; dir[4][3]= 1; // 4: 0 0 0 +1
}
// The last three directions change sign according to
// whether the site is odd or even.
// If periodic boundary conditions are used then the size
// of the lattice in each dimension must be even.
}
// Given that the direction table is defined,
// the directionality for a given direction
// is the weighted sum of the signs of the directions,
// weighted by lowness of index.
// This is used only in trace_single_cluster() in CLUSTERS.C.
/*---------------------------*/
void set_directionalities(void)
{
int r, index, sum;
if ( direction_table_is_parity_dependent )
adjust_direction_table(0);
for ( r=0; r<coord_num; r++ )
{
sum = 0;
for ( index=0; index<dimensionality; index++ )
sum += dir[r][index]*(dimensionality-index);
directionality[r] = sum;
}
}
// Given a site of a certain parity, and a direction to a nn site,
// this function returns the direction from the nn site back to the given site.
/*------------------------------------*/
int inverse_direction(int parity, int r)
{
int index, ir, nn_parity=parity;
if ( direction_table_is_parity_dependent )
adjust_direction_table(parity);
for ( index=0; index<dimensionality; index++ )
{
inverse_dir[index] = -dir[r][index];
nn_parity += abs(dir[r][index]);
}
nn_parity %= 2;
if ( nn_parity != parity && direction_table_is_parity_dependent )
adjust_direction_table(nn_parity);
for ( ir=0; ir<coord_num; ir++ )
{
for ( index=0; index<dimensionality; index++ )
{
if ( dir[ir][index] != inverse_dir[index] )
break;
}
if ( index == dimensionality )
break;
}
if ( ir == coord_num )
{
printf("\nError when getting inverse direction.\n");
exit(1);
}
if ( nn_parity != parity && direction_table_is_parity_dependent )
adjust_direction_table(parity);
return ( ir );
}
// Where lattice is parity-dependent this function is used
// to adjust the direction table at odd or even sites.
/*-----------------------------------*/
void adjust_direction_table(int parity)
{
if ( honeycomb_lattice )
dir[2][1-major_axis] = ( parity ? -1 : 1 );
else if ( diamond_lattice )
dir[2][1-major_axis] = dir[3][2] = ( parity ? -1 : 1 );
else if ( hyperdiamond_lattice_4d )
dir[2][1] = dir[3][2] = dir[4][3] = ( parity ? -1 : 1 );
}