//  ISS_DEF.H
//  #defines
//  © 2021 Peter J. Meyer

#define true  (1)
#define false (0)
#define loop while(true)

#define ADD_CODE missing_code(__FILE__,__LINE__);

#define SHORT_INTS_PER_SWENDSEN_WANG_STACK_PUSH (dimensionality)
#define SHORT_INTS_PER_WOLFF_STACK_PUSH (dimensionality+1)

#define NUM_MULTIPLE_RESULTS (4)
//  Maximum number of results saved in multiple_temperature_results[][][] array.
//  0 = magnetization
//  1 = Binder cumulant
//  2 = internal energy
//  3 = specific heat

#define CHECK_ADMISSABILITY true            //  used in FILE_IO.C
#define DOES_PERCOLATION_THRESHOLDS false
#define TIMING_DIAGNOSTICS false
#define SAVE_MEASUREMENTS false
#define COMPLETE_SAMPLE_ON_ESCAPE true
#define WR_ST_DEV_AUTOCORRELATON  true
#define FREE_BOUNDARY_CONDITIONS_POSSIBLE true
#define RECORD_SPIN_DISTANCES true
#define MAJOR_AXIS_SPECIFICATION_PERMITTED false
#define ALTERNATIVE_SPIN_SELECTIONS false

#define TETRAHEDRAL_LATTICE_IMPLEMENTED false
//  Tetrahedral lattice has coordination number 12,
//  so this would require all storage for bonds information
//  to be expanded from unsigned char (8 bits) to unsigned short int (16 bits).

//  Defines used in determination of percolation thresholds.
#define MAX_ITERATIONS    (30)
#define NUM_CONCENTRATIONS (6)  
//  Concentration range divided into NUM_CONCENTRATIONS-1 parts.

#define NUM_LATTICE_TYPES (9+TETRAHEDRAL_LATTICE_IMPLEMENTED)

#define J ((double)1.0)
//  J represents the interaction energy.
//  A larger interaction energy implies that transitions to higher-energy states
//  are less probable, so with larger J the spin system changes more slowly.

//  #defines for the PRNGs

#define PRNG1_NAME "ran2()"
//  These are names of functions:
#define INIT_PRNG1 init_ran2
#define PRNG1 ran2
#define NUM_PRNG1_CALLS num_ran2_calls
#define RESET_NUM_PRNG1_CALLS reset_num_ran2_calls
#define PRNG1_PERIOD_EXCEEDED ran2_period_exceeded

#define NON_EXISTENT (-10000)

//  Minima and maxima

#define MIN_SIZE             (4)    //  minimum lattice size
#define MAX_SIZE          (2048)    //  maximum lattice size
#define MIN_SIZE_PT         (20)    //  minimum size in determination of perc. thr.
//  For maximum sizes see max_size[] in ISS_VAR.H.

#define MIN_CONCENTRATION  (0.001)          //  site and bond concentration
#define MAX_CONCENTRATION  (1.0)
#define MIN_TEMPERATURE    (0.001)
#define MAX_TEMPERATURE    (50.0)
#define MAX_NUM_TEMPERATURES (40)
#define MIN_PRECISION      (2)              //  Used in determination of
#define MAX_PRECISION      (6)              //  percolation threshold.
#define MIN_MAJOR_AXIS     (0)              //  Used with honeycome
#define MAX_MAJOR_AXIS     (1)              //  and diamond lattices.
#define MAX_DIMENSIONALITY (4)              //  Used for array sizes.
#define MIN_NUM_CONFIGURATIONS_PT (100)     //  only for determination of percolation threshold
#define MAX_NUM_CONFIGURATIONS   (100000)   //  max. num. of site configurations
#define MAX_NUM_SPIN_ASSIGNMENTS (100000)   //  max. num. of spin assignments
#define MAX_NUM_REPETITIONS      (500)      //  max. num. runs for each spin assignment
#define MAX_STEP_LENGTH     (10000)     //  max. number of MCS between measurements
#define MIN_NUM_TIME_SLICES (2)        //  no. of time slices includes initial state
#define MAX_NUM_TIME_SLICES (10001)     //  max. number of measurements
                                        //  MAX_STEP_LENGTH * MAX_NUM_TIME_SLICES 
                                        //  must be less than 2^32 
#define MIN_PERCENTAGE_RANGE_FOR_MEAN   (1)
#define MAX_PERCENTAGE_RANGE_FOR_MEAN (100)
#define MIN_Q_VALUE         (2)
#define MAX_Q_VALUE        (15)         //  9 for a stack of 1 MB.  For larger q
                                        //  the stack size must be increased.
                                        //  TEST WITH LARGER STACK
#define MAX_COORD_NUM       (8) 
//  MAX_COORD_NUM cannot be increased without significant changes to the code.

#define MAX_NUM_SPANNING_CLUSTERS (64)

//  Spin values for Ising model

#define UP_SPIN    (1)
#define DOWN_SPIN (-1)

//  Spin values for q-state Potts model range from 1 through q.

//  Types of clusters 

#define CT_NN            (1)
#define CT_OPEN_BOND     (2)
#define CT_SPIN          (3)
#define CT_SWENDSEN_WANG (4)

//  Date formats

#define ISO 0
#define EUR 1
#define US  2

//  ASCII characters

#define TAB        (9)
#define LINEFEED  (10)
#define CONTROL_T (20)
#define ESCAPE    (27)
#define SPACE     (32)

//  The following used in ALLOC.C and in FILE_IO.C
#define NUM_MAGNETIZATION_COMPONENTS   (4)
#define NUM_INTERNAL_ENERGY_COMPONENTS (3)
#define NUM_AUTOCORRELATION_COMPONENTS (2)

#define MAX_DIVISORS (60)
#define PREFERRED_NUM_DIVISORS (6)

//  Bit masks

#define BIT1_0   (1)    //  00000001
#define BIT1_1   (2)    //  00000010
#define BIT1_2   (4)    //  00000100
#define BIT1_3   (8)    //  00001000 
#define BIT1_4  (16)    //  00010000
#define BIT1_5  (32)    //  00100000 
#define BIT1_6  (64)    //  01000000
#define BIT1_7 (128)    //  10000000 

#define BIT0_0 (254)    //  11111110
#define BIT0_1 (253)    //  11111101
#define BIT0_2 (251)    //  11111011
#define BIT0_3 (247)    //  11110111 
#define BIT0_4 (239)    //  11101111
#define BIT0_5 (223)    //  11011111 
#define BIT0_6 (191)    //  10111111
#define BIT0_7 (127)    //  01111111 

#define IN_SPANNING_CLUSTER     BIT1_4           //  Bit pattern 00010000 
#define VISITED                 BIT1_5           //  Bit pattern 00100000
#define BOUNDARY                BIT1_6           //  Bit pattern 01000000
#define OCCUPIED                BIT1_7           //  Bit pattern 10000000
#define OCCUPIED_BY_UP_SPIN     BIT1_7           //  Bit pattern 10000000
#define OCCUPIED_BY_DOWN_SPIN  (BIT1_7|BIT1_0)   //  Bit pattern 10000001

#define NOT_IN_SPANNING_CLUSTER BIT0_4           //  Bit pattern 11101111
#define UNVISITED               BIT0_5           //  Bit pattern 11011111
#define UNOCCUPIED              BIT0_7           //  Bit pattern 01111111

//  Macros

#define IS_BOUNDARY_SITE_2(i,j)     ( sites2[i][j] & BOUNDARY )
#define IS_BOUNDARY_SITE_3(i,j,k)   ( sites3[i][j][k] & BOUNDARY )
#define IS_BOUNDARY_SITE_4(i,j,k,l) ( sites4[i][j][k][l] & BOUNDARY )

#define SITE_IS_OCCUPIED_2(i,j)     ( i<0 ? false : sites2[i][j] & OCCUPIED )
#define SITE_IS_OCCUPIED_3(i,j,k)   ( i<0 ? false : sites3[i][j][k] & OCCUPIED )
#define SITE_IS_OCCUPIED_4(i,j,k,l) ( i<0 ? false : sites4[i][j][k][l] & OCCUPIED )

#define MARK_SITE_AS_VISITED_2(i,j)     ( sites2[i][j] |= VISITED )
#define MARK_SITE_AS_VISITED_3(i,j,k)   ( sites3[i][j][k] |= VISITED )
#define MARK_SITE_AS_VISITED_4(i,j,k,l) ( sites4[i][j][k][l] |= VISITED )

#define SITE_IS_VISITED_2(i,j)      ( i<0 ? false : sites2[i][j] & VISITED )
#define SITE_IS_VISITED_3(i,j,k)    ( i<0 ? false : sites3[i][j][k] & VISITED )
#define SITE_IS_VISITED_4(i,j,k,l)  ( i<0 ? false : sites4[i][j][k][l] & VISITED )

#define MARK_SITE_IN_SPANNING_CLUSTER_2(i,j)     ( sites2[i][j] |= IN_SPANNING_CLUSTER )
#define MARK_SITE_IN_SPANNING_CLUSTER_3(i,j,k)   ( sites3[i][j][k] |= IN_SPANNING_CLUSTER )
#define MARK_SITE_IN_SPANNING_CLUSTER_4(i,j,k,l) ( sites4[i][j][k][l] |= IN_SPANNING_CLUSTER )