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