//  PRECOMP.C
//  Precompoutes nn sites
//  © 2021 Peter J. Meyer

#include "iss.h"

static void adjust_indices_2(void);

/*--------------------------*/
void precompute_nn_sites(void)
{
int i, j, k, l, r;

switch ( dimensionality )
    {
    case 2:
    for ( i=0; i<size; i++ )
        {
        for ( j=0; j<size; j++ )
            {
            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];
                }
            adjust_indices_2();
            for ( r=0; r<coord_num; r++ )           
                {
                precomp_nn_sites2[i][j][r][0] = nn_sites[r][0];  
                precomp_nn_sites2[i][j][r][1] = nn_sites[r][1];
                }
            }
        }
    break;

    case 3:
    for ( i=0; i<size; i++ )
        {
        for ( j=0; j<size; j++ )
            {
            for ( k=0; k<size; k++ )
                {
                if ( direction_table_is_parity_dependent )
                    adjust_direction_table((i+j+k)%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];
                    nn_sites[r][2] = k + dir[r][2];
                    }
                adjust_indices_2();
                for ( r=0; r<coord_num; r++ )           
                    {
                    precomp_nn_sites3[i][j][k][r][0] = nn_sites[r][0];  
                    precomp_nn_sites3[i][j][k][r][1] = nn_sites[r][1];
                    precomp_nn_sites3[i][j][k][r][2] = nn_sites[r][2];
                    }
                }
            }
        }
    break;

    case 4:
    for ( i=0; i<size; i++ )
        {
        for ( j=0; j<size; j++ )
            {
            for ( k=0; k<size; k++ )
                {
                for ( l=0; l<size; l++ )
                    {
                    if ( direction_table_is_parity_dependent )
                        adjust_direction_table((i+j+k+l)%2);
                    for ( r=0; r<coord_num; r++ )           //  For each direction
                        {
                        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];
                        }
                    adjust_indices_2();
                    for ( r=0; r<coord_num; r++ )           
                        {
                        precomp_nn_sites4[i][j][k][l][r][0] = nn_sites[r][0];  
                        precomp_nn_sites4[i][j][k][l][r][1] = nn_sites[r][1];
                        precomp_nn_sites4[i][j][k][l][r][2] = nn_sites[r][2];
                        precomp_nn_sites4[i][j][k][l][r][3] = nn_sites[r][3];
                        }
                    }
                }
            }
        }   
    break;
    }
}

/*------------------------------*/
static void adjust_indices_2(void)
{
int r, index;

for ( r=0; r<coord_num; r++ )           //  For each direction
    {
    for ( index=0; index<dimensionality; index++ )
        {
        if ( nn_sites[r][index] < 0 )
            nn_sites[r][index] = ( free_boundary_conditions ? 
                NON_EXISTENT :  nn_sites[r][index] + size );
        else if ( nn_sites[r][index] >= size )
            nn_sites[r][index] = ( free_boundary_conditions ? 
                NON_EXISTENT : nn_sites[r][index] - size );
        if ( nn_sites[r][index] == NON_EXISTENT )
            {
            nn_sites[r][0] = NON_EXISTENT;
            break;
            }
        }
    }
}