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 /** The minimum x coordinate of the container. */
29 /** The maximum x coordinate of the container. */
31 /** The minimum y coordinate of the container. */
33 /** The maximum y coordinate of the container. */
35 /** The box length in the x direction, set to (bx-ax)/nx. */
37 /** The box length in the y direction, set to (by-ay)/ny. */
39 /** The inverse box length in the x direction. */
41 /** The inverse box length in the y direction. */
43 /** The number of boxes in the x direction. */
45 /** The number of boxes in the y direction. */
47 /** A constant, set to the value of nx multiplied by ny, which
48 * is used in the routines which step through boxes in
51 /** A boolean value that determines if the x coordinate in
54 /** A boolean value that determines if the y coordinate in
57 /** This array holds the number of particles within each
58 * computational box of the container. */
60 /** This array holds the maximum amount of particle memory for
61 * each computational box of the container. If the number of
62 * particles in a particular box ever approaches this limit,
63 * more is allocated using the add_particle_memory() function.
66 /** This array holds the numerical IDs of each particle in each
67 * computational box. */
69 /** A two dimensional array holding particle positions. For the
70 * derived container_poly class, this also holds particle
73 container_2d(double xa
,double xb
,double ya
,double yb
,int xn
,int yn
,bool xper
,bool yper
,int memi
);
75 void import(FILE *fp
=stdin
);
76 /** Imports a list of particles from a file.
77 * \param[in] filename the file to read from. */
78 inline void import(const char *filename
) {
79 FILE *fp(voropp_safe_fopen(filename
,"r"));
83 void draw_particles(FILE *fp
=stdout
);
84 /** Dumps all the particle positions and IDs to a file.
85 * \param[in] filename the file to write to. */
86 inline void draw_particles(const char *filename
) {
87 FILE *fp(voropp_safe_fopen(filename
,"w"));
91 void draw_particles_pov(FILE *fp
=stdout
);
92 /** Dumps all the particles positions in POV-Ray format.
93 * \param[in] filename the file to write to. */
94 inline void draw_particles_pov(const char *filename
) {
95 FILE *fp(voropp_safe_fopen(filename
,"w"));
96 draw_particles_pov(fp
);
99 void draw_cells_gnuplot(FILE *fp
=stdout
);
100 /** Computes the Voronoi cells for all particles and saves the
101 * output in gnuplot format.
102 * \param[in] filename the file to write to. */
103 inline void draw_cells_gnuplot(const char *filename
) {
104 FILE *fp(voropp_safe_fopen(filename
,"w"));
105 draw_cells_gnuplot(fp
);
108 void draw_cells_pov(FILE *fp
=stdout
);
109 /** Computes the Voronoi cells for all particles and saves the
110 * output in POV-Ray format.
111 * \param[in] filename the file to write to. */
112 inline void draw_cells_pov(const char *filename
) {
113 FILE *fp(voropp_safe_fopen(filename
,"w"));
117 void print_custom(const char *format
,FILE *fp
=stdout
);
118 /** Computes the Voronoi cells for all particles in the
119 * container, and for each cell, outputs a line containing
120 * custom information about the cell structure. The output
121 * format is specified using an input string with control
122 * sequences similar to the standard C printf() routine.
123 * \param[in] format the format of the output lines, using
124 * control sequences to denote the different
126 * \param[in] filename the file to write to. */
127 inline void print_custom(const char *format
,const char *filename
) {
128 FILE *fp(voropp_safe_fopen(filename
,"w"));
129 print_custom(format
,fp
);
132 double sum_cell_areas();
133 void compute_all_cells();
134 /** An overloaded version of the compute_cell_sphere routine,
135 * that sets up the x and y variables.
136 *\param[in,out] c a reference to a voronoicell object.
137 * \param[in] (i,j) the coordinates of the block that the test
139 * \param[in] ij the index of the block that the test particle
140 * is in, set to i+nx*j.
141 * \param[in] s the index of the particle within the test
143 * \return False if the Voronoi cell was completely removed
144 * during the computation and has zero volume, true otherwise.
146 inline bool compute_cell_sphere(voronoicell_2d
&c
,int i
,int j
,int ij
,int s
) {
147 double x
=p
[ij
][2*s
],y
=p
[ij
][2*s
+1];
148 return compute_cell_sphere(c
,i
,j
,ij
,s
,x
,y
);
150 bool compute_cell_sphere(voronoicell_2d
&c
,int i
,int j
,int ij
,int s
,double x
,double y
);
151 bool initialize_voronoicell(voronoicell_2d
&c
,double x
,double y
);
152 void put(int n
,double x
,double y
);
155 inline bool put_locate_block(int &ij
,double &x
,double &y
);
156 inline bool put_remap(int &ij
,double &x
,double &y
);
157 void add_particle_memory(int i
);
158 /** Custom int function, that gives consistent stepping for
159 * negative numbers. With normal int, we have
160 * (-1.5,-0.5,0.5,1.5) -> (-1,0,0,1). With this routine, we
161 * have (-1.5,-0.5,0.5,1.5) -> (-2,-1,0,1). */
162 inline int step_int(double a
) {return a
<0?int(a
)-1:int(a
);}
163 /** Custom modulo function, that gives consistent stepping for
164 * negative numbers. */
165 inline int step_mod(int a
,int b
) {return a
>=0?a
%b
:b
-1-(b
-1-a
)%b
;}
166 /** Custom integer division function, that gives consistent
167 * stepping for negative numbers. */
168 inline int step_div(int a
,int b
) {return a
>=0?a
/b
:-1+(a
+1)/b
;}
169 friend class voropp_loop_2d
;
173 /** \brief A class to handle loops on regions of the container handling
174 * non-periodic and periodic boundary conditions.
176 * Many of the container routines require scanning over a rectangular sub-grid
177 * of blocks, and the routines for handling this are stored in the
178 * voropp_loop_2d class. A voropp_loop_2d class can first be initialized to
179 * either calculate the subgrid which is within a distance r of a vector
180 * (vx,vy,vz), or a subgrid corresponding to a rectangular box. The routine
181 * inc() can then be successively called to step through all the blocks within
184 class voropp_loop_2d
{
186 voropp_loop_2d(container_2d
&con
);
187 int init(double vx
,double vy
,double r
,double &px
,double &py
);
188 int init(double xmin
,double xmax
,double ymin
,double ymax
,double &px
,double &py
);
189 int inc(double &px
,double &py
);
190 /** The current block index in the x direction, referencing a
191 * real cell in the range 0 to nx-1. */
193 /** The current block index in the y direction, referencing a
194 * real cell in the range 0 to ny-1. */
197 const double boxx
,boxy
,xsp
,ysp
,ax
,ay
;
199 const bool xperiodic
,yperiodic
;
201 int i
,j
,ai
,bi
,aj
,bj
,s
;
203 /** Custom modulo function, that gives consistent stepping for
204 * negative numbers. */
205 inline int step_mod(int a
,int b
) {return a
>=0?a
%b
:b
-1-(b
-1-a
)%b
;}
206 /** Custom integer division function, that gives consistent
207 * stepping for negative numbers. */
208 inline int step_div(int a
,int b
) {return a
>=0?a
/b
:-1+(a
+1)/b
;}
209 /** Custom int function, that gives consistent stepping for
210 * negative numbers. With normal int, we have
211 * (-1.5,-0.5,0.5,1.5) -> (-1,0,0,1). With this routine, we
212 * have (-1.5,-0.5,0.5,1.5) -> (-2,-1,0,1). */
213 inline int step_int(double a
) {return a
<0?int(a
)-1:int(a
);}