1 /** \file container_2d.hh
2 * \brief Header file for the container_2d class. */
4 #ifndef VOROPP_CONTAINER_2D_HH
5 #define VOROPP_CONTAINER_2D_HH
17 /** \brief A class representing the whole 2D simulation region.
19 * The container class represents the whole simulation region. The
20 * container constructor sets up the geometry and periodicity, and divides
21 * the geometry into rectangular grid of blocks, each of which handles the
22 * particles in a particular area. Routines exist for putting in particles,
23 * importing particles from standard input, and carrying out Voronoi
27 /** degbugging aid. */
29 /** The minimum x coordinate of the container. */
31 /** The maximum x coordinate of the container. */
33 /** The minimum y coordinate of the container. */
35 /** The maximum y coordinate of the container. */
37 /** The box length in the x direction, set to (bx-ax)/nx. */
39 /** The box length in the y direction, set to (by-ay)/ny. */
41 /** The inverse box length in the x direction. */
43 /** The inverse box length in the y direction. */
45 /** The number of boxes in the x direction. */
47 /** The number of boxes in the y direction. */
49 /** A constant, set to the value of nx multiplied by ny, which
50 * is used in the routines which step through boxes in
53 /** A boolean value that determines if the x coordinate in
56 /** A boolean value that determines if the y coordinate in
59 /** A boolean value that specifies whether the domain will be convex or non-convex.
60 * affected methods include cell_2d:plane, container_2d:import, container_2d:initialize_vo
62 * and container_2d:compute_cellsphere. */
64 /** This array holds the number of particles within each
65 * computational box of the container. */
68 /** This array holds the maximum amount of particle memory for
69 * each computational box of the container. If the number of
70 * particles in a particular box ever approaches this limit,
71 * more is allocated using the add_particle_memory() function.
74 /** This array holds the numerical IDs of each particle in each
75 * computational box. */
77 /** For each computational box, this holds the boundary walls that pass through that box.
80 /** A two dimensional array holding particle positions. For the
81 * derived container_poly class, this also holds particle
84 /** A two dimensional array for holding the number of labels per
85 * particle, plus other status information. */
87 /** A two dimensional array of pointers to label information.
90 /** An array created from *tmp and is referenced my *soip. soi
91 * stands for "spheres of influence" */
93 /** The current number of boundary points. */
95 /** Specifies the memory allocation for the boundary points. */
97 /** This array holds the vertices of the non-convex domain. If
98 * the domain is convex this variable is not initialized. The
99 * format is (bnds[0],bnds[1])=(x1,y1) for some (x1,y1)
100 * boundary point and (bnds[2],bnds[3])=(x2,y2) is the next
101 * vertex in the boundary from (x1,y1) if we are going
104 /** Information about how the boundary vertices are connected.
105 * A single integer is stored for each vertex, giving the index
106 * of the connecting vertex in the counter-clockwise sense. */
108 /** Contains information about which points are boundary points,
109 i.e. lie at a nonconvexity. **/
111 /** Contains information about which boundary points are problem points **/
114 container_2d(double xa
,double xb
,double ya
,double yb
,int xn
,int yn
,bool xper
,bool yper
,bool convex_
,int memi
);
117 int crossproductz(double x1
, double y1
, double x2
, double y2
);
118 void semi_circle_labelling(double x1
, double y1
, double x2
, double y2
, int wid
);
119 void add_edb_memory(int i
);
120 void initial_cut(voronoicell_2d
&c
, double x
, double y
, int bid
);
121 void initial_cut_nonconvex(voronoicell_2d
&c
, double x
, double y
, int bid
);
122 void import(FILE *fp
=stdin
);
123 void container_projection(double x
, double y
, double &ccy
, double &ccy
, double &nx
, double &ny
);
124 /** Imports a list of particles from a file.
125 * \param[in] filename the file to read from. */
126 inline void import(const char *filename
) {
127 FILE *fp(voropp_safe_fopen(filename
,"r"));
131 void Perp_vector(double x1
, double y1
, double &x1
, double &y1
, int dcp
);
132 void tag_walls(double x1
, double y1
, double x2
, double y2
, int wid
);
133 inline void tag(int wallid
, int box
) {
134 int length
=wid
[box
][0], *a
;
137 for(int j
=0; j
<length
; j
++){
140 delete [] wid
[box
]; wid
[box
]=a
;
142 wid
[box
][length
]=wallid
;
145 void draw_particles(FILE *fp
=stdout
);
146 /** Dumps all the particle positions and IDs to a file.
147 * \param[in] filename the file to write to. */
148 inline void draw_particles(const char *filename
) {
149 FILE *fp(voropp_safe_fopen(filename
,"w"));
153 void draw_particles_pov(FILE *fp
=stdout
);
154 /** Dumps all the particles positions in POV-Ray format.
155 * \param[in] filename the file to write to. */
156 inline void draw_particles_pov(const char *filename
) {
157 FILE *fp(voropp_safe_fopen(filename
,"w"));
158 draw_particles_pov(fp
);
161 void draw_cells_gnuplot(FILE *fp
=stdout
);
162 /** Computes the Voronoi cells for all particles and saves the
163 * output in gnuplot format.
164 * \param[in] filename the file to write to. */
165 inline void draw_cells_gnuplot(const char *filename
) {
166 FILE *fp(voropp_safe_fopen(filename
,"w"));
167 draw_cells_gnuplot(fp
);
170 void draw_cells_pov(FILE *fp
=stdout
);
171 /** Computes the Voronoi cells for all particles and saves the
172 * output in POV-Ray format.
173 * \param[in] filename the file to write to. */
174 inline void draw_cells_pov(const char *filename
) {
175 FILE *fp(voropp_safe_fopen(filename
,"w"));
179 void draw_boundary(FILE *fp
=stdout
);
180 inline void draw_boundary(const char *filename
) {
181 FILE *fp(voropp_safe_fopen(filename
,"w"));
185 void print_custom(const char *format
,FILE *fp
=stdout
);
186 /** Computes the Voronoi cells for all particles in the
187 * container, and for each cell, outputs a line containing
188 * custom information about the cell structure. The output
189 * format is specified using an input string with control
190 * sequences similar to the standard C printf() routine.
191 * \param[in] format the format of the output lines, using
192 * control sequences to denote the different
194 * \param[in] filename the file to write to. */
195 inline void print_custom(const char *format
,const char *filename
) {
196 FILE *fp(voropp_safe_fopen(filename
,"w"));
197 print_custom(format
,fp
);
200 double sum_cell_areas();
201 void compute_all_cells();
203 /** An overloaded version of the compute_cell_sphere routine,
204 * that sets up the x and y variables.
205 *\param[in,out] c a reference to a voronoicell object.
206 * \param[in] (i,j) the coordinates of the block that the test
208 * \param[in] ij the index of the block that the test particle
209 * is in, set to i+nx*j.
210 * \param[in] s the index of the particle within the test
212 * \return False if the Voronoi cell was completely removed
213 * during the computation and has zero volume, true otherwise.
215 inline bool compute_cell_sphere(voronoicell_2d
&c
,int i
,int j
,int ij
,int s
) {
216 double x
=p
[s
][2*ij
],y
=p
[s
][2*ij
+1];
217 return compute_cell_sphere(c
,i
,j
,ij
,s
,x
,y
);
219 bool compute_cell_sphere(voronoicell_2d
&c
,int i
,int j
,int ij
,int s
,double x
,double y
);
220 bool initialize_voronoicell(voronoicell_2d
&c
,double x
,double y
);
221 bool initialize_voronoicell_nonconvex(voronoicell_2d
&c
,double x
, double y
, int bid
);
222 bool initialize_voronoicell_boundary(voronoicell_2d
&c
, double x
, double y
, int bid
);
223 bool OKCuttingParticle(double gx
, double gy
, int gbox
, int gindex
, double cx
, double cy
,
224 int cbox
, int cindex
, bool boundary
, int bid
);
225 void put(int n
,double x
,double y
, int bndloc
);
228 /** A temporary array used in label creation. */
230 /** The next free position in the temporary label array. */
232 /** The end of the temporary label array. */
234 inline bool put_locate_block(int &ij
,double &x
,double &y
);
235 inline bool put_remap(int &ij
,double &x
,double &y
);
236 inline double max(double a
, double b
) {return b
<a
?a
:b
;}
237 inline double min(double a
, double b
) {return (b
<a
)?b
:a
;}
238 inline double dist(double x1
,double y1
,double x2
,double y2
) {
239 return pow((((y2
-y1
)*(y2
-y1
))+((x2
-x1
)*(x2
-x1
))),.5);
241 void create_label_table();
242 void add_temporary_label_memory();
243 void add_particle_memory(int i
);
244 void add_boundary_memory();
245 /** Custom int function, that gives consistent stepping for
246 * negative numbers. With normal int, we have
247 * (-1.5,-0.5,0.5,1.5) -> (-1,0,0,1). With this routine, we
248 * have (-1.5,-0.5,0.5,1.5) -> (-2,-1,0,1). */
249 inline int step_int(double a
) {return a
<0?int(a
)-1:int(a
);}
250 /** Custom modulo function, that gives consistent stepping for
251 * negative numbers. */
252 inline int step_mod(int a
,int b
) {return a
>=0?a
%b
:b
-1-(b
-1-a
)%b
;}
253 /** Custom integer division function, that gives consistent
254 * stepping for negative numbers. */
255 inline int step_div(int a
,int b
) {return a
>=0?a
/b
:-1+(a
+1)/b
;}
256 friend class voropp_loop_2d
;
260 /** \brief A class to handle loops on regions of the container handling
261 * non-periodic and periodic boundary conditions.
263 * Many of the container routines require scanning over a rectangular sub-grid
264 * of blocks, and the routines for handling this are stored in the
265 * voropp_loop_2d class. A voropp_loop_2d class can first be initialized to
266 * either calculate the subgrid which is within a distance r of a vector
267 * (vx,vy,vz), or a subgrid corresponding to a rectangular box. The routine
268 * inc() can then be successively called to step through all the blocks within
271 class voropp_loop_2d
{
273 voropp_loop_2d(container_2d
&con
);
274 int init(double vx
,double vy
,double r
,double &px
,double &py
);
275 int init(double xmin
,double xmax
,double ymin
,double ymax
,double &px
,double &py
);
276 int inc(double &px
,double &py
);
277 /** The current block index in the x direction, referencing a
278 * real cell in the range 0 to nx-1. */
280 /** The current block index in the y direction, referencing a
281 * real cell in the range 0 to ny-1. */
284 const double boxx
,boxy
,xsp
,ysp
,ax
,ay
;
286 const bool xperiodic
,yperiodic
;
288 int i
,j
,ai
,bi
,aj
,bj
,s
;
290 /** Custom modulo function, that gives consistent stepping for
291 * negative numbers. */
292 inline int step_mod(int a
,int b
) {return a
>=0?a
%b
:b
-1-(b
-1-a
)%b
;}
293 /** Custom integer division function, that gives consistent
294 * stepping for negative numbers. */
295 inline int step_div(int a
,int b
) {return a
>=0?a
/b
:-1+(a
+1)/b
;}
296 /** Custom int function, that gives consistent stepping for
297 * negative numbers. With normal int, we have
298 * (-1.5,-0.5,0.5,1.5) -> (-1,0,0,1). With this routine, we
299 * have (-1.5,-0.5,0.5,1.5) -> (-2,-1,0,1). */
300 inline int step_int(double a
) {return a
<0?int(a
)-1:int(a
);}