irregular.cc – Dealing with irregular particle packings
A common problem is to find an adequate method of prescribing boundary conditions when faced with an irregular cluster of particles. If the standard approach was used of placing a group of particles within a larger container, then the Voronoi cells for particles at the edges of the packing would be very large and extend off to the edges of the container.
This example presents a simple method of dealing with this problem, without creating very large Voronoi cells. Usually, when Voro++ creates Voronoi cells, it first initializes them to fill the entire container, and then cuts them down by making plane cuts that are the perpendicular bisectors with neighboring particles. To stop the Voronoi cells from becoming very large, one approach is to first initialize them to be a small polyhedron surrounding each particle. Voro++ will then cut them down based upon nearby particles, but the cells will never stretch beyond the initial polyhedron.
In this code, this is achieved by creating a new wall class called
wall_initial_shape
. When created, the class constructs a
dodecahedron in a voronoicell
class. Usually, wall classes
function by applying plane cuts to Voronoi cells prior to the main computation.
However, here, the wall class replaces the entire cell with a dodecahedron,
which will then be used in the main computation. For the image above, for particles
ont the outside, the silhouettes of the dodecahedron are visible, but within
the packing, plane cuts are applied that will match the usual Voronoi
tessellation.
The figure to the right represents a single Voronoi cell and particle from the packing above. The initial dodecahedron shape is shown in yellow. Once the cell is constructed, some of the original dodecahedron faces are still visible, but additional planes have been introduced to match the Voronoi tessellation
The use of a dodecahedron is arbitrary, and could be modified to any shape in the constructor on lines 28 to 34. One approach may be initialize every Voronoi cell to be an approximation to a sphere, in cases where it may be desirable for each particle to have influence up to a certain radius.
Code listing
1: // Irregular packing 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,x_max=6; 12: const double y_min=-6,y_max=6; 13: const double z_min=-3,z_max=9; 14: 15: // Golden ratio constants 16: const double Phi=0.5*(1+sqrt(5.0)); 17: const double phi=0.5*(1-sqrt(5.0)); 18: 19: // Set up the number of blocks that the container is divided 20: // into. 21: const int n_x=5,n_y=5,n_z=5; 22: 23: // Create a wall class that, whenever called, will replace the Voronoi cell 24: // with a prescribed shape, in this case a dodecahedron 25: class wall_initial_shape : public wall { 26: public: 27: wall_initial_shape() { 28: 29: // Create a dodecahedron 30: v.init(-2,2,-2,2,-2,2); 31: v.plane(0,Phi,1);v.plane(0,-Phi,1);v.plane(0,Phi,-1); 32: v.plane(0,-Phi,-1);v.plane(1,0,Phi);v.plane(-1,0,Phi); 33: v.plane(1,0,-Phi);v.plane(-1,0,-Phi);v.plane(Phi,1,0); 34: v.plane(-Phi,1,0);v.plane(Phi,-1,0);v.plane(-Phi,-1,0); 35: }; 36: bool point_inside(double x,double y,double z) {return true;} 37: bool cut_cell(voronoicell &c,double x,double y,double z) { 38: 39: // Set the cell to be equal to the dodecahedron 40: c=v; 41: return true; 42: } 43: bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) { 44: 45: // Set the cell to be equal to the dodecahedron 46: c=v; 47: return true; 48: } 49: private: 50: voronoicell v; 51: }; 52: 53: int main() { 54: 55: // Create a container with the geometry given above. This is bigger 56: // than the particle packing itself. 57: container con(x_min,x_max,y_min,y_max,z_min,z_max,n_x,n_y,n_z, 58: false,false,false,8); 59: 60: // Create the "initial shape" wall class and add it to the container 61: wall_initial_shape(wis); 62: con.add_wall(wis); 63: 64: // Import the irregular particle packing 65: con.import("pack_irregular"); 66: 67: // Save the particles and Voronoi cells in POV-Ray format 68: con.draw_particles_pov("irregular_p.pov"); 69: con.draw_cells_pov("irregular_v.pov"); 70: }