custom_output.cc – Customized output for different statistics

Packing of 216 spheres in a cube, colored by the number of faces of the Voronoi cellsKey to particle colors

One the key routines in the container class is print_all_custom, which can be used to output a large variety of statistics about the Voronoi cells in a packing.

The routine works in a similar way to the C printf() function. A format string must be given that can contain text plus special control sequences beginning with percentage signs. For each particle, a line is created in the output file where each control sequence is expanded to give a different piece of information about the cell. A full list of control sequences is provided, and in this example, three different output files are created.

The first example, on lines 33–35, creates an output string which contains particle positions, and also information about the number of vertices, edges, and faces that each Voronoi cell has. The format string is given as:

ID=%i, pos=(%x,%y,%z), vertices=%w, edges=%g, faces=%s

The output file contains lines such as:

ID=1, pos=(-1.63353,-1.00818,0.499764), vertices=20, edges=30, faces=12

Due to the way that particles are stored in Voro++ during the computation, the order of the particles in the output file may not match those in the input packing. However, Voro++ does contain mechanisms for preserving the order if necessary: see the -o option in the command-line utility or the discussion voro_order class in the loops.cc code. The second output example on line 42 lists the number of faces and the total surface area of the cell, and then gives consectutive lists with information about the faces:

Each of these lists is guaranteed to have exactly the same number of entries, and the faces are considered in the same order, which aids in any subsequent data analysis. The final example on line 47 prints information about the Voronoi cell volume and the position of the cell centroid.

The custom output routines can contain complete information about the structure of the Voronoi cells, and it is intended that these could be subsequently post-processed to carry out a variety of analyses. The example perl script “custom_output.pl” reads in the first custom output and makes a POV-Ray script whereby each particle is colored according to the number of faces its Voronoi cell has. The file “custom_output.pov” can then be rendered following the same procedure as described previously to give the above image.

Code listing

 1: // Custom output 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: // Set up constants for the container geometry
11: const double x_min=-3,x_max=3;
12: const double y_min=-3,y_max=3;
13: const double z_min=0,z_max=6;
14: 
15: // Set up the number of blocks that the container is divided
16: // into.
17: const int n_x=3,n_y=3,n_z=3;
18: 
19: int main() {
20: 
21:         // Create a container with the geometry given above, and make it
22:         // non-periodic in each of the three coordinates. Allocate space for
23:         // eight particles within each computational block.
24:         container con(x_min,x_max,y_min,y_max,z_min,z_max,n_x,n_y,n_z,
25:                         false,false,false,8);
26: 
27:         // Import the monodisperse test packing and output the Voronoi
28:         // tessellation in gnuplot and POV-Ray formats.
29:         con.import("pack_six_cube");
30: 
31:         // Do a custom output routine to store the number of vertices, edges,
32:         // and faces of each Voronoi cell
33:         con.print_custom(
34:                 "ID=%i, pos=(%x,%y,%z), vertices=%w, edges=%g, faces=%s",
35:                 "packing.custom1");
36: 
37:         // Do a custom output routine to store a variety of face-based
38:         // statistics. Store the particle ID and position, the number of faces
39:         // the total face area, the order of each face, the areas of each face,
40:         // the vertices making up each face, and the neighboring particle (or
41:         // wall) corresponding to each face.
42:         con.print_custom("%i %q %s %F %a %f %t %l %n","packing.custom2");
43: 
44:         // Do a custom output routine that outputs the particle IDs and
45:         // positions, plus the volume and the centroid position relative to the
46:         // particle center
47:         con.print_custom("%i %q %v %c","packing.custom3");
48: 
49:         // Also create POV-Ray output of the Voronoi cells for use in the
50:         // rendering
51:         con.draw_cells_pov("pack_six_cube_v.pov");
52: }

Perl script listing

 1: #!/usr/bin/perl
 2: 
 3: # Open the custom output from the custom_output.cc program
 4: open A,"packing.custom1" or die "Can't open file \"packing.custom1\"\n";
 5: 
 6: # Open the POV-Ray file
 7: open B,">custom_output_p.pov" or die "Can't open output file\n";
 8: 
 9: # Loop over all lines in the packing.custom1 file
10: while(<A>) {
11: 
12:         # Use a regular expression to get the particle position and the number
13:         # of faces of the Voronoi cell. These will be stored in the variables
14:         # $1 and $2.
15:         m/pos=\((.*)\).*faces=(\d*)/;
16: 
17:         # Print a sphere to the POV-Ray file, giving it a different texture
18:         # depending on the number of faces of the Voronoi cell
19:         print B "sphere{<$1>,0.5 texture{t$2}}\n";
20: }
21: 
22: # Close the two files
23: close A;
24: close B;