1 // Voro++, a 3D cell-based Voronoi library
3 // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email : chr@alum.mit.edu
5 // Date : July 1st 2008
8 * \brief Source code for the command line utility. */
12 // A guess for the memory allocation per region
15 // A maximum allowed number of regions, to prevent enormous amounts of memory
17 const int max_regions
=16777216;
19 // This message gets displayed if the command line arguments are incorrect
20 // or if the user requests the help flag
22 cout
<< "Voro++ version 0.2, by Chris H. Rycroft (UC Berkeley/LBL)\n\n";
23 cout
<< "Syntax: voro++ [opts] <length_scale> <x_min> <x_max> <y_min>\n";
24 cout
<< " <y_max> <z_min> <z_max> <filename>\n\n";
25 cout
<< "<length_scale> should be set to a typical particle diameter,\n";
26 cout
<< "or typical distance between particles. It is used to configure\n";
27 cout
<< "the code for maximum efficiency.\n\n";
28 cout
<< "Available options:\n";
29 cout
<< " -g : Turn on the gnuplot output to <filename.gnu>\n";
30 cout
<< " -h/--help : Print this information\n";
31 cout
<< " -n : Turn on the neighbor tracking procedure\n";
32 cout
<< " -p : Make container periodic in all three directions\n";
33 cout
<< " -px : Make container periodic in the x direction\n";
34 cout
<< " -py : Make container periodic in the y direction\n";
35 cout
<< " -pz : Make container periodic in the z direction\n";
36 cout
<< " -r : Assume the input file has an extra coordinate for radii\n";
37 cout
<< " -wc [7] : Add a cylinder wall object, centered on (x1,x2,x3),\n";
38 cout
<< " pointing in (x4,x5,x6), radius x7\n";
39 cout
<< " -wo [7] : Add a conical wall object, apex at (x1,x2,x3), axis\n";
40 cout
<< " along (x4,x5,x6), angle x7 in radians\n";
41 cout
<< " -ws [4] : Add a sphere wall object, centered on (x1,x2,x3),\n";
42 cout
<< " with radius x4\n";
43 cout
<< " -wp [4] : Add a plane wall object, with normal (x1,x2,x3),\n";
44 cout
<< " and displacement x4" << endl
;
47 // Prints an error message. This is called when the program is unable to make
48 // sense of the command line options.
49 void error_message() {
50 cerr
<< "Unrecognized command line options; type \"voro++ -h\" for more information." << endl
;
53 // Global variables to set the wall memory allocation, and the current number
55 int wall_mem
=init_wall_size
,wall_count
=0;
57 // A pointer to the wall pointer array
60 // A routine to double up the wall memory allocation if needed
61 void add_wall_memory() {
64 if (wall_mem
>max_wall_size
) cerr
<< "Too many walls allocated. Try recompiling by boosting the value of max_wall_size in config.hh" << endl
;
65 nwp
=new wall
*[wall_mem
];
66 for(int i
=0;i
<wall_count
;i
++) nwp
[i
]=wp
[i
];
71 // A routine to deallocate the dynamically created wall objects
72 void wall_deallocate() {
73 for(int i
=0;i
<wall_count
;i
++) delete wp
[i
];
77 int main(int argc
,char **argv
) {
79 bool gnuplot_output
=false,neighbor_track
=false,polydisperse
=false;
80 bool xperiodic
=false,yperiodic
=false,zperiodic
=false;
82 wp
=new wall
*[init_wall_size
];
84 // If there's one argument, check to see if it's requesting help.
85 // Otherwise, bail out with an error.
87 if (strcmp(argv
[1],"-h")==0||strcmp(argv
[1],"--help")==0) {
88 help_message();return 0;
90 error_message();return 1;
94 // If there aren't enough command line arguments, then bail out
97 error_message();return 1;
100 // We have enough arguments. Now start searching for command line
103 if (strcmp(argv
[i
],"-g")==0) {
105 } else if (strcmp(argv
[i
],"-h")==0||strcmp(argv
[i
],"--help")==0) {
106 help_message();return 0;
107 } else if (strcmp(argv
[i
],"-n")==0) {
109 } else if (strcmp(argv
[i
],"-p")==0) {
110 xperiodic
=yperiodic
=zperiodic
=true;
111 } else if (strcmp(argv
[i
],"-px")==0) {
113 } else if (strcmp(argv
[i
],"-py")==0) {
115 } else if (strcmp(argv
[i
],"-pz")==0) {
117 } else if (strcmp(argv
[i
],"-r")==0) {
119 } else if (strcmp(argv
[i
],"-ws")==0) {
120 if (wall_count
==wall_mem
) add_wall_memory();
122 fpoint w0
=atof(argv
[i
++]),w1
=atof(argv
[i
++]);
123 fpoint w2
=atof(argv
[i
++]),w3
=atof(argv
[i
]);
124 wp
[wall_count
++]=new wall_sphere(w0
,w1
,w2
,w3
,j
);
125 cout
<< "Sphere" << w0
<< " " << w1
<< " " << w2
<< " " << w3
<< endl
;
127 } else if (strcmp(argv
[i
],"-wp")==0) {
128 if (wall_count
==wall_mem
) add_wall_memory();
130 fpoint w0
=atof(argv
[i
++]),w1
=atof(argv
[i
++]);
131 fpoint w2
=atof(argv
[i
++]),w3
=atof(argv
[i
]);
132 wp
[wall_count
++]=new wall_plane(w0
,w1
,w2
,w3
,j
);
134 } else if (strcmp(argv
[i
],"-wc")==0) {
135 if (wall_count
==wall_mem
) add_wall_memory();
137 fpoint w0
=atof(argv
[i
++]),w1
=atof(argv
[i
++]);
138 fpoint w2
=atof(argv
[i
++]),w3
=atof(argv
[i
++]);
139 fpoint w4
=atof(argv
[i
++]),w5
=atof(argv
[i
++]);
140 fpoint w6
=atof(argv
[i
]);
141 wp
[wall_count
++]=new wall_cylinder(w0
,w1
,w2
,w3
,w4
,w5
,w6
,j
);
143 } else if (strcmp(argv
[i
],"-wo")==0) {
144 if (wall_count
==wall_mem
) add_wall_memory();
146 fpoint w0
=atof(argv
[i
++]),w1
=atof(argv
[i
++]);
147 fpoint w2
=atof(argv
[i
++]),w3
=atof(argv
[i
++]);
148 fpoint w4
=atof(argv
[i
++]),w5
=atof(argv
[i
++]);
149 fpoint w6
=atof(argv
[i
]);
150 wp
[wall_count
++]=new wall_cone(w0
,w1
,w2
,w3
,w4
,w5
,w6
,j
);
153 error_message();return 1;
158 // Read in the dimensions of the test box, and estimate the number of
159 // boxes to divide the region up into
160 fpoint ls
=atof(argv
[i
]);
161 fpoint xmin
=atof(argv
[i
+1]),xmax
=atof(argv
[i
+2]);
162 fpoint ymin
=atof(argv
[i
+3]),ymax
=atof(argv
[i
+4]);
163 fpoint zmin
=atof(argv
[i
+5]),zmax
=atof(argv
[i
+6]);
165 // Check that the length scale is positive and reasonably large
168 cerr
<< "The length scale must be positive" << endl
;
170 cerr
<< "The length scale is smaller than the safe limit of " << tolerance
<< ".\n";
171 cerr
<< "Either increase the particle length scale, or recompile with a\n";
172 cerr
<< "different limit." << endl
;
179 // Compute the number regions based on the length scale provided. If
180 // the total number exceeds a cutoff then bail out, to prevent making
181 // a massive memory allocation.
182 int nx
=int((xmax
-xmin
)*ls
)+1;
183 int ny
=int((ymax
-ymin
)*ls
)+1;
184 int nz
=int((zmax
-zmin
)*ls
)+1;
186 if (nx
*ny
*nz
>max_regions
) {
187 cerr
<< "Number of computational blocks (" << nxyz
<< ") exceeds the maximum\n";
188 cerr
<< "allowed of " << max_regions
<< ". Either increase the particle\n";
189 cerr
<< "length scale, or recompile with an increased maximum." << endl
;
194 // Prepare output filename
195 sprintf(buffer
,"%s.vol",argv
[i
+7]);
197 // Now switch depending on whether polydispersity was enabled
199 container_poly
con(xmin
,xmax
,ymin
,ymax
,zmin
,zmax
,nx
,ny
,nz
,
200 xperiodic
,yperiodic
,zperiodic
,memory
);
201 for(j
=0;j
<wall_count
;j
++) con
.add_wall(*wp
[j
]);
202 con
.import(argv
[i
+7]);
204 if (neighbor_track
) con
.print_all_neighbor(buffer
);
205 else con
.print_all(buffer
);
207 if (gnuplot_output
) {
208 sprintf(buffer
,"%s.gnu",argv
[i
+7]);
209 con
.draw_cells_gnuplot(buffer
);
212 container
con(xmin
,xmax
,ymin
,ymax
,zmin
,zmax
,nx
,ny
,nz
,
213 xperiodic
,yperiodic
,zperiodic
,memory
);
214 for(j
=0;j
<wall_count
;j
++) con
.add_wall(*wp
[j
]);
215 con
.import(argv
[i
+7]);
217 if (neighbor_track
) con
.print_all_neighbor(buffer
);
218 else con
.print_all(buffer
);
220 if (gnuplot_output
) {
221 sprintf(buffer
,"%s.gnu",argv
[i
+7]);
222 con
.draw_cells_gnuplot(buffer
);