box_cut.cc – Cutting a cell by a grid of points in box

Cutting a Voronoi cell by a rectangular box of points

The container class in Voro++ stores particles within a grid of rectangular boxes. Efficient computation of the Voronoi cell of a particular particle requires that we only consider as few neighboring particles as possible. As part of this procedure, the code needs know whether a particular box in the grid can possibly cut a partially computed Voronoi cell or not. However, it is unclear a priori exactly what volume of space the particles within a particular box can influence.

This example code gives some intuition as to the influence that a particular box can have. In line 19, the code initializes a voronoicell object to be a cube of side length 16. The code then proceeds in lines 23–29 to cut the cell, by considering a 10 × 10 × 10 lattice of particles within a unit cube centered at (1.5,1.5,1.5). The resulting cell is output in Gnuplot format to the file “box_cut.gnu”. In lines 35 and 36, the voronoicell class is reused to output the unit cube of test points to the file “box_cut.points”.

These two outputs are plotted above. The cut Voronoi cell shows seven planar patches, connected with thick red bands that represent approximations to curved surfaces. The central planar patch is due to (1,1,1), that is the point closest to the center of the Voronoi cell. The other six planar patches are due to particles at the other vertices of the cube, excluding (2,2,2), which does not play a role. Asymptotically, the orientation of these six planar patches is important. The container class has a private function corner_test that

For the case shown here, the closest point from the test cube to the Voronoi cell center is at a vertex. Qualitatively different behavior is seen if an edge or face is aligned with the cell center. These possibilities can be explored by changing the values of cx, cy, and cz.

Code listing

 1: // Box cutting example code
 2: //
 3: // Author   : Chris H. Rycroft (LBL / UC Berkeley)
 4: // Email    : chr@alum.mit.edu
 5: // Date     : August 30th 2011
 6: 
 7: #include "voro++.hh"
 8: using namespace voro;
 9: 
10: // Parameters controlling the center of the test box
11: const double cx=1.5,cy=1.5,cz=1.5;
12: 
13: int main() {
14:         double x,y,z;
15:         voronoicell v;
16: 
17:         // Initialize the Voronoi cell to be a cube of side length 16, centered
18:         // on the origin
19:         v.init(-8,8,-8,8,-8,8);
20: 
21:         // Cut by a grid of points in a box of width one, centered on
22:         // (cx,cy,cz)
23:         for(x=cx-0.5;x<cx+0.55;x+=0.1) for(y=cy-0.5;y<cy+0.55;y+=0.1)
24:                 for(z=cz-0.5;z<cz+0.55;z+=0.1) v.plane(x,y,z);
25: 
26:         // Output the Voronoi cell in gnuplot format
27:         v.draw_gnuplot(0,0,0,"box_cut.gnu");
28: 
29:         // Now make a small file that contains the test box
30:         v.init(cx-0.5,cx+0.5,cy-0.5,cy+0.5,cz-0.5,cz+0.5);
31:         v.draw_gnuplot(0,0,0,"box_cut.points");
32: }