cylinder.cc – A cylindrical particle packing
The direct cell-by-cell construction that Voro++ uses makes it particularly easy to handle non-standard boundary conditions, since the Voronoi cells can be individually tailored by applying additional plane cuts.
Voro++ contains a mechanism for adding walls to a container class, that
create additional plane cuts during the cell computation. This is done through
a pure virtual wall
class, that represents any unspecified wall.
This class contains two main functions. The first is
point_inside()
that returns whether a given point is within the
wall or not. The second is cut_cell()
that takes a
voronoicell
, and adds plane cuts due to the presence of the wall.
In the header file wall.hh
, the classes wall_plane
,
wall_cylinder
, and wall_cone
are defined to handle
plane, cylinder, and conical walls; other wall types could be added by the
user.
This example code demonstrates the use of the cylindrical wall object. The
code makes use of the file “pack_cylinder” that was generated from
a DEM simulation pouring
2300 particles into a cylindrical container of radius six. In line 22 of the
code, a container class is initialized with non-periodic boundaries. In line
26, a wall_cylinder
class is constructed. The first three
arguments specify a point on the axis of the cylinder, the next three specify
the direction of the axis, and the final one determines the cylinder radius. On
line 27, the add_wall()
function is called, that passes a pointer
to the wall to the container class so that it can be referenced by the Voronoi
cell computation routines. In the remainder of the code, particle positions are
imported and the cells are computed in POV-Ray format.
The image above shows the computed Voronoi cells, rendered using the header file “cylinder.pov”. The cells mesh nicely against the wall, although some discrepancies can be seen, particularly near the top. This is because the cylindrical wall is approximated with a single plane cut. For dense packings this can produce good results, although it may become less accurate for sparsely-distributed particles. Better accuracy could be obtained by approximating the wall by more plane cuts.
Movies
- Small rotating movie of the cell construction: High quality QuickTime (15 MB) / Low quality AVI (7 MB)
- Large rotating movie of the cell construction: High quality QuickTime (44 MB) / Low quality AVI (24 MB)
Code listing
1: // Cylindrical wall example code 2: // 3: // Author : Chris H. Rycroft (LBL / UC Berkeley) 4: // Email : [email protected] 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=-6.5,x_max=6.5; 12: const double y_min=-6.5,y_max=6.5; 13: const double z_min=0,z_max=18.5; 14: 15: // Set the computational grid size 16: const int n_x=7,n_y=7,n_z=14; 17: 18: int main() { 19: // Create a container with the geometry given above, and make it 20: // non-periodic in each of the three coordinates. Allocate space for 21: // eight particles within each computational block. 22: container con(x_min,x_max,y_min,y_max,z_min,z_max,n_x,n_y,n_z, 23: false,false,false,8); 24: 25: // Add a cylindrical wall to the container 26: wall_cylinder cyl(0,0,0,0,0,1,6); 27: con.add_wall(cyl); 28: 29: // Import the particles from a file 30: con.import("pack_cylinder"); 31: 32: // Output the particle positions in POV-Ray format 33: con.draw_particles_pov("cylinder_p.pov"); 34: 35: // Output the Voronoi cells in POV-Ray format 36: con.draw_cells_pov("cylinder_v.pov"); 37: }