degenerate.cc – Degenerate vertices

Degen Degen Degen

This example demonstrates the ability of the code to handle degenerate vertices, that are connected to more than three neighbors, that occur when the cutting planes precisely intersect with existing vertices. To make the routines tolerant to numerical errors, Voro++ takes the approach that a cutting plane intersects an existing vertex if it is within a small tolerance of that vertex – this amount can be set in the source file “config.hh”.

In this example, a Voronoi cell is constructed using plane cuts at specific angles that lead to high order vertices in each of the six coordinate directions (x, y, z, -x, -y, -z). In lines 28 to 36, a number of planes cuts are applied, by rotating around each coordinate direction.

The creation of the degenerate vertices requires significant internal reordering of memory. Once the cell is created, two diagnostic routines are carried out to ensure that the calculation is correct. The routine check_relations() ensures that the relation table describing how edges are linked to each other is current. The routine check_duplicates() makes sure that there are no duplicate edges between two vertices. The resulting cell is output in Gnuplot and POV-Ray formats, to the files “degenerate.gnu” and “degenerate_v.pov” respectively.

The left image above shows the POV-Ray output, using the header file “degenerate.pov”. We see vertices of order 32 in the coordinate directions, and there are also many vertices of order 4 that arise due to symmetry. The middle image shows the cell if the value of theta is changed to pi/4. The resulting cell has a very similar structure, although some edges are missing due to the planes from one direction perfectly matching with the planes from the neighboring direction. The right image shows the cell if theta=pi/4+0.25. For this value, the planes from one direction begin to interfere with the others, creating a pattern with many order 4 vertices.

Code listing

 1: // Degenerate Voronoi cell 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: const double pi=3.1415926535897932384626433832795;
11: 
12: // The number of planes to be cut around each coordinate axis
13: const int n=32;
14: const double step=2*pi/n;
15: 
16: // The angle (in radians) of the cutting planes from horizontal
17: const double theta=pi/4-0.25;
18: 
19: int main() {
20:         double x,y,z,phi;
21:         voronoicell v;
22: 
23:         // Initialize the Voronoi cell to be a cube of side length 2, centered
24:         // on the origin
25:         v.init(-1,1,-1,1,-1,1);
26: 
27:         // Plane cutting
28:         for(phi=0;phi<2*pi-0.5*step;phi+=step) {
29:                 x=cos(theta);y=cos(phi)*sin(theta);z=sin(phi)*sin(theta);
30:                 v.plane(x,y,z,1);
31:                 v.plane(-x,y,z,1);
32:                 v.plane(y,x,z,1);
33:                 v.plane(y,-x,z,1);
34:                 v.plane(y,z,x,1);
35:                 v.plane(y,z,-x,1);
36:         }
37: 
38:         // Check that the relation table is correct, and that there are no
39:         // duplicate edges
40:         v.check_relations();
41:         v.check_duplicates();
42: 
43:         // Output the Voronoi cell to a file in Gnuplot format
44:         v.draw_gnuplot(0,0,0,"degenerate.gnu");
45: 
46:         // Output the Voronoi cell to a file in POV-Ray format
47:         v.draw_pov(0,0,0,"degenerate_v.pov");
48: }