ParticleBuffer - Unit Cell RDF

The ParticleBuffer class is meant to replicate particles beyond a single image while respecting box periodicity. This example demonstrates how we can use this to compute the radial distribution function from a sample crystal’s unit cell.

[1]:
import freud
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from util import box_2d_to_points

Here, we create a box to represent the unit cell and put two points inside. We plot the box and points below.

[2]:
box = freud.box.Box(Lx=2, Ly=2, xy=np.sqrt(1/3), is2D=True)
points = np.asarray([[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]])
corners = box_2d_to_points(box)
ax = plt.gca()
box_patch = plt.Polygon(corners[:, :2])
patch_collection = matplotlib.collections.PatchCollection([box_patch], edgecolors='black', alpha=0.4)
ax.add_collection(patch_collection)
plt.scatter(points[:, 1], points[:, 2])
plt.show()
../../_images/examples_module_intros_Box-ParticleBuffer_3_0.png

Next, we create a ParticleBuffer instance and have it compute the “buffer” particles that lie outside the first periodicity. These positions are stored in the buffer_positions attribute. The corresponding buffer_ids array gives a mapping from the index of the buffer particle to the index of the particle it was replicated from, in the original array of points. Finally, the buffer_box attribute returns a larger box, expanded from the original box to contain the replicated points.

[3]:
pbuff = freud.box.ParticleBuffer(box)
pbuff.compute(points, 6, images=True)
print(pbuff.buffer_particles[:10], '...')
[[ 0.6547002  1.5        0.       ]
 [ 1.8094003  3.5        0.       ]
 [ 2.9641018  5.5        0.       ]
 [-3.9641013 -6.5        0.       ]
 [-2.809401  -4.4999995  0.       ]
 [-1.6547002 -2.5000005  0.       ]
 [ 1.5000002 -0.5        0.       ]
 [ 2.6547008  1.5        0.       ]
 [ 3.8094003  3.5        0.       ]
 [ 4.964102   5.5        0.       ]] ...

Below, we plot the original unit cell and the replicated buffer points and buffer box.

[4]:
plt.scatter(points[:, 0], points[:, 1])
plt.scatter(pbuff.buffer_particles[:, 0], pbuff.buffer_particles[:, 1])
box_patch = plt.Polygon(corners[:, :2])
buff_corners = box_2d_to_points(pbuff.buffer_box)
buff_box_patch = plt.Polygon(buff_corners[:, :2])
patch_collection = matplotlib.collections.PatchCollection(
    [box_patch, buff_box_patch], facecolors=['blue', 'orange'],
    edgecolors='black', alpha=0.2)
plt.gca().add_collection(patch_collection)
plt.show()
../../_images/examples_module_intros_Box-ParticleBuffer_7_0.png

Finally, we can plot the radial distribution function (RDF) of this replicated system, using a value of rmax that is larger than the size of the original box. This allows us to see the interaction of the original particles in ref_points with their replicated neighbors from the buffer in points.

[5]:
rdf = freud.density.RDF(rmax=5, dr=0.02)
rdf.compute(pbuff.buffer_box, ref_points=points, points=pbuff.buffer_particles)
plt.plot(rdf.R, rdf.RDF)
plt.show()
../../_images/examples_module_intros_Box-ParticleBuffer_9_0.png