For constructing neighbour lists, while accounting for PBCs, we have applied a scheme of using 'cubic indexes' for each atom in our FCC lattice.
NOTE: Our simulation cell is cubic, but it could be cuboidal too & this indexing would still be good.
Cubic Index: Each atom is assigned a unique 4-tuple (m,n,p,s) of integers.
The 3-tuple (m,n,p) indexes the cubic Bravais cell. Each cubic cell has 4 atoms which are distinguished by their 's' index according to the following rule: (atom_position) --- ('s' index)
v0: (0,0,0) -- s=0
v1: (1/2,1/2,0) -- s=1
v2: (0,1/2,1/2) -- s=2
v3: (1/2,0,1/2) -- s=3
(v1,v2,v3 are the FCC basis vectors)
Each time a lattice is constructed with cubic indexing, a pickled dict: 'cubicIndexMap.pickle' is specifying a map from (m,n,p,s)-->ID is also written.
A map from the integer Bravais indices (a,b,c), which are integers specified along the primitive FCC basis vectors, can be specified to the cubic indices using only integer math.
F: (a,b,c)-->(m,n,p,s)
(To construct F we write the position of the atom first in Bravais space and then expand the basis vectors into 3D cartesian space, as specified above, noting that EITHER 2 vector components OR none can at most be half-integers - depending upon the value of s).
The map F: (a,b,c)-->(m,n,p,s) is,
m,v[1] = divmod(a+c,2)
n,v[2] = divmod(b+a,2)
p,v[3] = divmod(b+c,2)
s is assigned by checking if 'v' is v0,v1,v2 or v3.
NOTE: divmod () is a built-in python function which returns the quotient & the remainder of a division.
Applying PBCs:
When finding Bravais neighbours, one can quickly map the cubic index and then to the ID (using the pickled map). In case periodic boundaries need to be handled, we merely need to 'mod' cubic indices (m,n,p) with the number of cubic cells along a cartesian axis. NOTE: 's' should be unchanged.
See: the function getCubicIndex() in
/home/ahasan/usr/local/simulations/fcc-3d/disordered/lattice/pickFCCplane.py