Voronoi 3D Weights

Issue #160 resolved
Bradley Dice created an issue

Currently, voronoi computes the neighbor list weights correctly for 2D. It weights the edges by the length of the ridge separating the neighboring points. However, this does not work in 3D, since the ridge area should give its weight.

This snippet gives sample weights in 2D and may be helpful for constructing the 3D test.

import freud
import numpy as np
L = 10
rbuf = 3
positions = np.array([[i, j, 0] for i in range(3) for j in range(3)]).astype(np.float32)
fbox = freud.box.Box.square(L)
vor = freud.voronoi.Voronoi(fbox)
vor.computeNeighbors(positions, fbox, rbuf)
nlist = vor.getNeighborList()
nlist = nlist.filter(nlist.index_i == 4)
for (i, j, w) in zip(nlist.index_i, nlist.index_j, nlist.weights):
  print(i, j, w)
# 4 3 1.0
# 4 5 1.0
# 4 1 1.0
# 4 7 1.0

Comments (4)

  1. Bradley Dice reporter

    This code snippet demonstrates a separate problem: the neighborlist does not wrap around the periodic box. Even though the first particle should have a total of 6 neighbors, counting those in opposite wrapped corners of the box, it appears to have only 3 neighbors. To solve this, the VoronoiBuffer code will need to track the particle IDs when it adds buffer particles.

    import freud
    import numpy as np
    L = 4
    rbuf = L/2
    perturbation = 0
    positions = np.array([[((i+perturbation*(np.random.rand()-0.5)) % L) - L/2,
                           ((j+perturbation*(np.random.rand()-0.5)) % L) - L/2,
                           ((k+perturbation*(np.random.rand()-0.5)) % L) - L/2]
                           for i in range(L)
                           for j in range(L)
                           for k in range(L)]).astype(np.float32)
    print(positions)
    fbox = freud.box.Box.cube(L)
    print(fbox)
    vor = freud.voronoi.Voronoi(fbox)
    vor.computeNeighbors(positions, fbox, rbuf)
    nlist = vor.getNeighborList()
    unique_indices, counts = np.unique(nlist.index_i, return_counts=True)
    for ui in unique_indices:
        print('Index', ui, 'has', counts[ui], 'neighbors.')
        ilist = nlist.copy()
        ilist = ilist.filter(ilist.index_i == ui)
        for (i, j, w) in zip(ilist.index_i, ilist.index_j, ilist.weights):
          print(i, j, w)
    
  2. Log in to comment