Reset platonic code.
[voro++.git] / branches / dynamic / src / cmd_line.cc
blobb64cd758f4781f22d0421074ae7613817b0ee215
1 // Voro++, a 3D cell-based Voronoi library
2 //
3 // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email : chr@alum.mit.edu
5 // Date : July 1st 2008
7 /** \file cmd_line.cc
8 * \brief Source code for the command line utility. */
10 #include "voro++.cc"
12 // A guess for the memory allocation per region
13 const int memory=8;
15 // A maximum allowed number of regions, to prevent enormous amounts of memory
16 // being allocated
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
21 void help_message() {
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
54 // of allocated walls
55 int wall_mem=init_wall_size,wall_count=0;
57 // A pointer to the wall pointer array
58 wall **wp;
60 // A routine to double up the wall memory allocation if needed
61 void add_wall_memory() {
62 wall **nwp;
63 wall_mem*=2;
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];
67 delete [] wp;
68 wp=nwp;
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];
74 delete [] wp;
77 int main(int argc,char **argv) {
78 int i=1,j=-7;
79 bool gnuplot_output=false,neighbor_track=false,polydisperse=false;
80 bool xperiodic=false,yperiodic=false,zperiodic=false;
81 char buffer[256];
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.
86 if (argc==2) {
87 if (strcmp(argv[1],"-h")==0||strcmp(argv[1],"--help")==0) {
88 help_message();return 0;
89 } else {
90 error_message();return 1;
94 // If there aren't enough command line arguments, then bail out
95 // with an error.
96 if (argc<9) {
97 error_message();return 1;
100 // We have enough arguments. Now start searching for command line
101 // options.
102 while(i+8<argc) {
103 if (strcmp(argv[i],"-g")==0) {
104 gnuplot_output=true;
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) {
108 neighbor_track=true;
109 } else if (strcmp(argv[i],"-p")==0) {
110 xperiodic=yperiodic=zperiodic=true;
111 } else if (strcmp(argv[i],"-px")==0) {
112 xperiodic=true;
113 } else if (strcmp(argv[i],"-py")==0) {
114 yperiodic=true;
115 } else if (strcmp(argv[i],"-pz")==0) {
116 zperiodic=true;
117 } else if (strcmp(argv[i],"-r")==0) {
118 polydisperse=true;
119 } else if (strcmp(argv[i],"-ws")==0) {
120 if (wall_count==wall_mem) add_wall_memory();
121 i++;
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;
126 j--;
127 } else if (strcmp(argv[i],"-wp")==0) {
128 if (wall_count==wall_mem) add_wall_memory();
129 i++;
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);
133 j--;
134 } else if (strcmp(argv[i],"-wc")==0) {
135 if (wall_count==wall_mem) add_wall_memory();
136 i++;
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);
142 j--;
143 } else if (strcmp(argv[i],"-wo")==0) {
144 if (wall_count==wall_mem) add_wall_memory();
145 i++;
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);
151 j--;
152 } else {
153 error_message();return 1;
155 i++;
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
166 if (ls<tolerance) {
167 if (ls<0) {
168 cerr << "The length scale must be positive" << endl;
169 } else {
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;
174 wall_deallocate();
175 return 0;
177 ls=1.8/ls;
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;
185 int nxyz=nx*ny*nz;
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;
190 wall_deallocate();
191 return 0;
194 // Prepare output filename
195 sprintf(buffer,"%s.vol",argv[i+7]);
197 // Now switch depending on whether polydispersity was enabled
198 if (polydisperse) {
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);
211 } else {
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);
225 return 0;