1 // Voro++, a 3D cell-based Voronoi library
3 // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email : chr@alum.mit.edu
5 // Date : August 30th 2011
7 /** \file container_prd.hh
8 * \brief Header file for the container_periodic_base and related classes. */
10 #ifndef VOROPP_CONTAINER_PRD_HH
11 #define VOROPP_CONTAINER_PRD_HH
21 #include "v_compute.hh"
22 #include "unitcell.hh"
23 #include "rad_option.hh"
27 /** \brief Class for representing a particle system in a 3D periodic
28 * non-orthogonal periodic domain.
30 * This class represents a particle system in a three-dimensional
31 * non-orthogonal periodic domain. The domain is defined by three periodicity
32 * vectors (bx,0,0), (bxy,by,0), and (bxz,byz,bz) that represent a
33 * parallelepiped. Internally, the class stores particles in the box 0<x<bx,
34 * 0<y<by, 0<z<bz, and constructs periodic images of particles that displaced
35 * by the three periodicity vectors when they are necessary for the
36 * computation. The internal memory structure for this class is significantly
37 * different from the container_base class in order to handle the dynamic
38 * construction of these periodic images.
40 * The class is derived from the unitcell class, which encapsulates information
41 * about the domain geometry, and the voro_base class, which encapsulates
42 * information about the underlying computational grid. */
43 class container_periodic_base
: public unitcell
, public voro_base
{
45 const double max_len_sq
;
46 /** The lower y index (inclusive) of the primary domain within
47 * the block structure. */
49 /** The lower z index (inclusive) of the primary domain within
50 * the block structure. */
52 /** The upper y index (exclusive) of the primary domain within
53 * the block structure. */
55 /** The upper z index (exclusive) of the primary domain within
56 * the block structure. */
58 /** The total size of the block structure (including images) in
61 /** The total size of the block structure (including images) in
64 /** The total number of blocks. */
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 /** This array holds the number of particles within each
74 * computational box of the container. */
76 /** This array holds the maximum amount of particle memory for
77 * each computational box of the container. If the number of
78 * particles in a particular box ever approaches this limit,
79 * more is allocated using the add_particle_memory() function.
82 /** An array holding information about periodic image
83 * construction at a given location. */
85 /** The initial amount of memory to allocate for particles
88 /** The amount of memory in the array structure for each
89 * particle. This is set to 3 when the basic class is
90 * initialized, so that the array holds (x,y,z) positions. If
91 * the container class is initialized as part of the derived
92 * class container_poly, then this is set to 4, to also hold
93 * the particle radii. */
95 container_periodic_base(double bx_
,double bxy_
,double by_
,double bxz_
,double byz_
,double bz_
,
96 int nx_
,int ny_
,int nz_
,int init_mem_
,int ps
);
97 ~container_periodic_base();
98 /** Prints all particles in the container, including those that
99 * have been constructed in image blocks. */
100 inline void print_all_particles() {
102 for(ijk
=0;ijk
<oxyz
;ijk
++) for(q
=0;q
<co
[ijk
];q
++)
103 printf("%d %g %g %g\n",id
[ijk
][q
],p
[ijk
][ps
*q
],p
[ijk
][ps
*q
+1],p
[ijk
][ps
*q
+2]);
106 /** Initializes the Voronoi cell prior to a compute_cell
107 * operation for a specific particle being carried out by a
108 * voro_compute class. The cell is initialized to be the
109 * pre-computed unit Voronoi cell based on planes formed by
110 * periodic images of the particle.
111 * \param[in,out] c a reference to a voronoicell object.
112 * \param[in] ijk the block that the particle is within.
113 * \param[in] q the index of the particle within its block.
114 * \param[in] (ci,cj,ck) the coordinates of the block in the
115 * container coordinate system.
116 * \param[out] (i,j,k) the coordinates of the test block
117 * relative to the voro_compute
119 * \param[out] (x,y,z) the position of the particle.
120 * \param[out] disp a block displacement used internally by the
121 * compute_cell routine.
122 * \return False if the plane cuts applied by walls completely
123 * removed the cell, true otherwise. */
124 template<class v_cell
>
125 inline bool initialize_voronoicell(v_cell
&c
,int ijk
,int q
,int ci
,int cj
,int ck
,int &i
,int &j
,int &k
,double &x
,double &y
,double &z
,int &disp
) {
127 double *pp
=p
[ijk
]+ps
*q
;
128 x
=*(pp
++);y
=*(pp
++);z
=*pp
;
132 /** Initializes parameters for a find_voronoi_cell call within
133 * the voro_compute template.
134 * \param[in] (ci,cj,ck) the coordinates of the test block in
135 * the container coordinate system.
136 * \param[in] ijk the index of the test block
137 * \param[out] (i,j,k) the coordinates of the test block
138 * relative to the voro_compute
140 * \param[out] disp a block displacement used internally by the
141 * find_voronoi_cell routine (but not needed
142 * in this instance.) */
143 inline void initialize_search(int ci
,int cj
,int ck
,int ijk
,int &i
,int &j
,int &k
,int &disp
) {
146 /** Returns the position of a particle currently being computed
147 * relative to the computational block that it is within. It is
148 * used to select the optimal worklist entry to use.
149 * \param[in] (x,y,z) the position of the particle.
150 * \param[in] (ci,cj,ck) the block that the particle is within.
151 * \param[out] (fx,fy,fz) the position relative to the block.
153 inline void frac_pos(double x
,double y
,double z
,double ci
,double cj
,double ck
,double &fx
,double &fy
,double &fz
) {
158 /** Calculates the index of block in the container structure
159 * corresponding to given coordinates.
160 * \param[in] (ci,cj,ck) the coordinates of the original block
161 * in the current computation, relative
162 * to the container coordinate system.
163 * \param[in] (ei,ej,ek) the displacement of the current block
164 * from the original block.
165 * \param[in,out] (qx,qy,qz) the periodic displacement that
166 * must be added to the particles
167 * within the computed block.
168 * \param[in] disp a block displacement used internally by the
169 * find_voronoi_cell and compute_cell routines
170 * (but not needed in this instance.)
171 * \return The block index. */
172 inline int region_index(int ci
,int cj
,int ck
,int ei
,int ej
,int ek
,double &qx
,double &qy
,double &qz
,int &disp
) {
173 int qi
=ci
+(ei
-nx
),qj
=cj
+(ej
-ey
),qk
=ck
+(ek
-ez
);
174 int iv(step_div(qi
,nx
));if(iv
!=0) {qx
=iv
*bx
;qi
-=nx
*iv
;} else qx
=0;
175 create_periodic_image(qi
,qj
,qk
);
176 return qi
+nx
*(qj
+oy
*qk
);
178 void create_all_images();
179 void check_compartmentalized();
181 void add_particle_memory(int i
);
182 void put_locate_block(int &ijk
,double &x
,double &y
,double &z
);
183 void put_locate_block(int &ijk
,double &x
,double &y
,double &z
,int &ai
,int &aj
,int &ak
);
184 /** Creates particles within an image block by copying them
185 * from the primary domain and shifting them. If the given
186 * block is aligned with the primary domain in the z-direction,
187 * the routine calls the simpler create_side_image routine
188 * where the image block may comprise of particles from up to
189 * two primary blocks. Otherwise is calls the more complex
190 * create_vertical_image where the image block may comprise of
191 * particles from up to four primary blocks.
192 * \param[in] (di,dj,dk) the coordinates of the image block to
194 inline void create_periodic_image(int di
,int dj
,int dk
) {
195 if(di
<0||di
>=nx
||dj
<0||dj
>=oy
||dk
<0||dk
>=oz
)
196 voro_fatal_error("Constructing periodic image for nonexistent point",VOROPP_INTERNAL_ERROR
);
198 if(dj
<ey
||dj
>=wy
) create_side_image(di
,dj
,dk
);
199 } else create_vertical_image(di
,dj
,dk
);
201 void create_side_image(int di
,int dj
,int dk
);
202 void create_vertical_image(int di
,int dj
,int dk
);
203 void put_image(int reg
,int fijk
,int l
,double dx
,double dy
,double dz
);
204 inline void remap(int &ai
,int &aj
,int &ak
,int &ci
,int &cj
,int &ck
,double &x
,double &y
,double &z
,int &ijk
);
207 /** \brief Extension of the container_periodic_base class for computing regular
208 * Voronoi tessellations.
210 * This class is an extension of the container_periodic_base that has routines
211 * specifically for computing the regular Voronoi tessellation with no
212 * dependence on particle radii. */
213 class container_periodic
: public container_periodic_base
, public radius_mono
{
215 container_periodic(double bx_
,double bxy_
,double by_
,double bxz_
,double byz_
,double bz_
,
216 int nx_
,int ny_
,int nz_
,int init_mem_
);
218 void put(int n
,double x
,double y
,double z
);
219 void put(int n
,double x
,double y
,double z
,int &ai
,int &aj
,int &ak
);
220 void put(particle_order
&vo
,int n
,double x
,double y
,double z
);
221 void import(FILE *fp
=stdin
);
222 void import(particle_order
&vo
,FILE *fp
=stdin
);
223 /** Imports a list of particles from an open file stream into
224 * the container. Entries of four numbers (Particle ID, x
225 * position, y position, z position) are searched for. If the
226 * file cannot be successfully read, then the routine causes a
228 * \param[in] filename the name of the file to open and read
230 inline void import(const char* filename
) {
231 FILE *fp
=safe_fopen(filename
,"r");
235 /** Imports a list of particles from an open file stream into
236 * the container. Entries of four numbers (Particle ID, x
237 * position, y position, z position) are searched for. In
238 * addition, the order in which particles are read is saved
239 * into an ordering class. If the file cannot be successfully
240 * read, then the routine causes a fatal error.
241 * \param[in,out] vo the ordering class to use.
242 * \param[in] filename the name of the file to open and read
244 inline void import(particle_order
&vo
,const char* filename
) {
245 FILE *fp
=safe_fopen(filename
,"r");
249 void compute_all_cells();
250 double sum_cell_volumes();
251 /** Dumps particle IDs and positions to a file.
252 * \param[in] vl the loop class to use.
253 * \param[in] fp a file handle to write to. */
254 template<class c_loop
>
255 void draw_particles(c_loop
&vl
,FILE *fp
) {
259 fprintf(fp
,"%d %g %g %g\n",id
[vl
.ijk
][vl
.q
],*pp
,pp
[1],pp
[2]);
262 /** Dumps all of the particle IDs and positions to a file.
263 * \param[in] fp a file handle to write to. */
264 inline void draw_particles(FILE *fp
=stdout
) {
265 c_loop_all_periodic
vl(*this);
266 draw_particles(vl
,fp
);
268 /** Dumps all of the particle IDs and positions to a file.
269 * \param[in] filename the name of the file to write to. */
270 inline void draw_particles(const char *filename
) {
271 FILE *fp
=safe_fopen(filename
,"w");
275 /** Dumps particle positions in POV-Ray format.
276 * \param[in] vl the loop class to use.
277 * \param[in] fp a file handle to write to. */
278 template<class c_loop
>
279 void draw_particles_pov(c_loop
&vl
,FILE *fp
) {
283 fprintf(fp
,"// id %d\nsphere{<%g,%g,%g>,s}\n",
284 id
[vl
.ijk
][vl
.q
],*pp
,pp
[1],pp
[2]);
287 /** Dumps all particle positions in POV-Ray format.
288 * \param[in] fp a file handle to write to. */
289 inline void draw_particles_pov(FILE *fp
=stdout
) {
290 c_loop_all_periodic
vl(*this);
291 draw_particles_pov(vl
,fp
);
293 /** Dumps all particle positions in POV-Ray format.
294 * \param[in] filename the name of the file to write to. */
295 inline void draw_particles_pov(const char *filename
) {
296 FILE *fp
=safe_fopen(filename
,"w");
297 draw_particles_pov(fp
);
300 /** Computes Voronoi cells and saves the output in gnuplot
302 * \param[in] vl the loop class to use.
303 * \param[in] fp a file handle to write to. */
304 template<class c_loop
>
305 void draw_cells_gnuplot(c_loop
&vl
,FILE *fp
) {
306 voronoicell
c(*this);double *pp
;
307 if(vl
.start()) do if(compute_cell(c
,vl
)) {
308 pp
=p
[vl
.ijk
]+ps
*vl
.q
;
309 c
.draw_gnuplot(*pp
,pp
[1],pp
[2],fp
);
312 /** Computes all Voronoi cells and saves the output in gnuplot
314 * \param[in] fp a file handle to write to. */
315 inline void draw_cells_gnuplot(FILE *fp
=stdout
) {
316 c_loop_all_periodic
vl(*this);
317 draw_cells_gnuplot(vl
,fp
);
319 /** Compute all Voronoi cells and saves the output in gnuplot
321 * \param[in] filename the name of the file to write to. */
322 inline void draw_cells_gnuplot(const char *filename
) {
323 FILE *fp
=safe_fopen(filename
,"w");
324 draw_cells_gnuplot(fp
);
327 /** Computes Voronoi cells and saves the output in POV-Ray
329 * \param[in] vl the loop class to use.
330 * \param[in] fp a file handle to write to. */
331 template<class c_loop
>
332 void draw_cells_pov(c_loop
&vl
,FILE *fp
) {
333 voronoicell
c(*this);double *pp
;
334 if(vl
.start()) do if(compute_cell(c
,vl
)) {
335 fprintf(fp
,"// cell %d\n",id
[vl
.ijk
][vl
.q
]);
336 pp
=p
[vl
.ijk
]+ps
*vl
.q
;
337 c
.draw_pov(*pp
,pp
[1],pp
[2],fp
);
340 /** Computes all Voronoi cells and saves the output in POV-Ray
342 * \param[in] fp a file handle to write to. */
343 inline void draw_cells_pov(FILE *fp
=stdout
) {
344 c_loop_all_periodic
vl(*this);
345 draw_cells_pov(vl
,fp
);
347 /** Computes all Voronoi cells and saves the output in POV-Ray
349 * \param[in] filename the name of the file to write to. */
350 inline void draw_cells_pov(const char *filename
) {
351 FILE *fp
=safe_fopen(filename
,"w");
355 /** Computes the Voronoi cells and saves customized information
357 * \param[in] vl the loop class to use.
358 * \param[in] format the custom output string to use.
359 * \param[in] fp a file handle to write to. */
360 template<class c_loop
>
361 void print_custom(c_loop
&vl
,const char *format
,FILE *fp
) {
362 int ijk
,q
;double *pp
;
363 if(contains_neighbor(format
)) {
364 voronoicell_neighbor
c(*this);
365 if(vl
.start()) do if(compute_cell(c
,vl
)) {
366 ijk
=vl
.ijk
;q
=vl
.q
;pp
=p
[ijk
]+ps
*q
;
367 c
.output_custom(format
,id
[ijk
][q
],*pp
,pp
[1],pp
[2],default_radius
,fp
);
370 voronoicell
c(*this);
371 if(vl
.start()) do if(compute_cell(c
,vl
)) {
372 ijk
=vl
.ijk
;q
=vl
.q
;pp
=p
[ijk
]+ps
*q
;
373 c
.output_custom(format
,id
[ijk
][q
],*pp
,pp
[1],pp
[2],default_radius
,fp
);
377 void print_custom(const char *format
,FILE *fp
=stdout
);
378 void print_custom(const char *format
,const char *filename
);
379 bool find_voronoi_cell(double x
,double y
,double z
,double &rx
,double &ry
,double &rz
,int &pid
);
380 /** Computes the Voronoi cell for a particle currently being
381 * referenced by a loop class.
382 * \param[out] c a Voronoi cell class in which to store the
384 * \param[in] vl the loop class to use.
385 * \return True if the cell was computed. If the cell cannot be
386 * computed because it was removed entirely for some reason,
387 * then the routine returns false. */
388 template<class v_cell
,class c_loop
>
389 inline bool compute_cell(v_cell
&c
,c_loop
&vl
) {
390 return vc
.compute_cell(c
,vl
.ijk
,vl
.q
,vl
.i
,vl
.j
,vl
.k
);
392 /** Computes the Voronoi cell for given particle.
393 * \param[out] c a Voronoi cell class in which to store the
395 * \param[in] ijk the block that the particle is within.
396 * \param[in] q the index of the particle within the block.
397 * \return True if the cell was computed. If the cell cannot be
398 * computed because it was removed entirely for some reason,
399 * then the routine returns false. */
400 template<class v_cell
>
401 inline bool compute_cell(v_cell
&c
,int ijk
,int q
) {
402 int k(ijk
/(nx
*oy
)),ijkt(ijk
-(nx
*oy
)*k
),j(ijkt
/nx
),i(ijkt
-j
*nx
);
403 return vc
.compute_cell(c
,ijk
,q
,i
,j
,k
);
405 /** Computes the Voronoi cell for a ghost particle at a given
407 * \param[out] c a Voronoi cell class in which to store the
409 * \param[in] (x,y,z) the location of the ghost particle.
410 * \return True if the cell was computed. If the cell cannot be
411 * computed, if it is removed entirely by a wall or boundary
412 * condition, then the routine returns false. */
413 template<class v_cell
>
414 inline bool compute_ghost_cell(v_cell
&c
,double x
,double y
,double z
) {
416 put_locate_block(ijk
,x
,y
,z
);
417 double *pp
=p
[ijk
]+3*co
[ijk
]++;
418 *(pp
++)=x
;*(pp
++)=y
;*(pp
++)=z
;
419 bool q
=compute_cell(c
,ijk
,co
[ijk
]-1);
424 voro_compute
<container_periodic
> vc
;
425 friend class voro_compute
<container_periodic
>;
428 /** \brief Extension of the container_periodic_base class for computing radical
429 * Voronoi tessellations.
431 * This class is an extension of container_periodic_base that has routines
432 * specifically for computing the radical Voronoi tessellation that depends
433 * on the particle radii. */
434 class container_periodic_poly
: public container_periodic_base
, public radius_poly
{
436 container_periodic_poly(double bx_
,double bxy_
,double by_
,double bxz_
,double byz_
,double bz_
,
437 int nx_
,int ny_
,int nz_
,int init_mem_
);
439 void put(int n
,double x
,double y
,double z
,double r
);
440 void put(int n
,double x
,double y
,double z
,double r
,int &ai
,int &aj
,int &ak
);
441 void put(particle_order
&vo
,int n
,double x
,double y
,double z
,double r
);
442 void import(FILE *fp
=stdin
);
443 void import(particle_order
&vo
,FILE *fp
=stdin
);
444 /** Imports a list of particles from an open file stream into
445 * the container_poly class. Entries of five numbers (Particle
446 * ID, x position, y position, z position, radius) are searched
447 * for. If the file cannot be successfully read, then the
448 * routine causes a fatal error.
449 * \param[in] filename the name of the file to open and read
451 inline void import(const char* filename
) {
452 FILE *fp
=safe_fopen(filename
,"r");
456 /** Imports a list of particles from an open file stream into
457 * the container_poly class. Entries of five numbers (Particle
458 * ID, x position, y position, z position, radius) are searched
459 * for. In addition, the order in which particles are read is
460 * saved into an ordering class. If the file cannot be
461 * successfully read, then the routine causes a fatal error.
462 * \param[in,out] vo the ordering class to use.
463 * \param[in] filename the name of the file to open and read
465 inline void import(particle_order
&vo
,const char* filename
) {
466 FILE *fp
=safe_fopen(filename
,"r");
470 void compute_all_cells();
471 double sum_cell_volumes();
472 /** Dumps particle IDs, positions and radii to a file.
473 * \param[in] vl the loop class to use.
474 * \param[in] fp a file handle to write to. */
475 template<class c_loop
>
476 void draw_particles(c_loop
&vl
,FILE *fp
) {
480 fprintf(fp
,"%d %g %g %g %g\n",id
[vl
.ijk
][vl
.q
],*pp
,pp
[1],pp
[2],pp
[3]);
483 /** Dumps all of the particle IDs, positions and radii to a
485 * \param[in] fp a file handle to write to. */
486 inline void draw_particles(FILE *fp
=stdout
) {
487 c_loop_all_periodic
vl(*this);
488 draw_particles(vl
,fp
);
490 /** Dumps all of the particle IDs, positions and radii to a
492 * \param[in] filename the name of the file to write to. */
493 inline void draw_particles(const char *filename
) {
494 FILE *fp
=safe_fopen(filename
,"w");
498 /** Dumps particle positions in POV-Ray format.
499 * \param[in] vl the loop class to use.
500 * \param[in] fp a file handle to write to. */
501 template<class c_loop
>
502 void draw_particles_pov(c_loop
&vl
,FILE *fp
) {
506 fprintf(fp
,"// id %d\nsphere{<%g,%g,%g>,%g}\n",
507 id
[vl
.ijk
][vl
.q
],*pp
,pp
[1],pp
[2],pp
[3]);
510 /** Dumps all the particle positions in POV-Ray format.
511 * \param[in] fp a file handle to write to. */
512 inline void draw_particles_pov(FILE *fp
=stdout
) {
513 c_loop_all_periodic
vl(*this);
514 draw_particles_pov(vl
,fp
);
516 /** Dumps all the particle positions in POV-Ray format.
517 * \param[in] filename the name of the file to write to. */
518 inline void draw_particles_pov(const char *filename
) {
519 FILE *fp(safe_fopen(filename
,"w"));
520 draw_particles_pov(fp
);
523 /** Computes Voronoi cells and saves the output in gnuplot
525 * \param[in] vl the loop class to use.
526 * \param[in] fp a file handle to write to. */
527 template<class c_loop
>
528 void draw_cells_gnuplot(c_loop
&vl
,FILE *fp
) {
529 voronoicell
c(*this);double *pp
;
530 if(vl
.start()) do if(compute_cell(c
,vl
)) {
531 pp
=p
[vl
.ijk
]+ps
*vl
.q
;
532 c
.draw_gnuplot(*pp
,pp
[1],pp
[2],fp
);
535 /** Compute all Voronoi cells and saves the output in gnuplot
537 * \param[in] fp a file handle to write to. */
538 inline void draw_cells_gnuplot(FILE *fp
=stdout
) {
539 c_loop_all_periodic
vl(*this);
540 draw_cells_gnuplot(vl
,fp
);
542 /** Compute all Voronoi cells and saves the output in gnuplot
544 * \param[in] filename the name of the file to write to. */
545 inline void draw_cells_gnuplot(const char *filename
) {
546 FILE *fp(safe_fopen(filename
,"w"));
547 draw_cells_gnuplot(fp
);
550 /** Computes Voronoi cells and saves the output in POV-Ray
552 * \param[in] vl the loop class to use.
553 * \param[in] fp a file handle to write to. */
554 template<class c_loop
>
555 void draw_cells_pov(c_loop
&vl
,FILE *fp
) {
556 voronoicell
c(*this);double *pp
;
557 if(vl
.start()) do if(compute_cell(c
,vl
)) {
558 fprintf(fp
,"// cell %d\n",id
[vl
.ijk
][vl
.q
]);
559 pp
=p
[vl
.ijk
]+ps
*vl
.q
;
560 c
.draw_pov(*pp
,pp
[1],pp
[2],fp
);
563 /** Computes all Voronoi cells and saves the output in POV-Ray
565 * \param[in] fp a file handle to write to. */
566 inline void draw_cells_pov(FILE *fp
=stdout
) {
567 c_loop_all_periodic
vl(*this);
568 draw_cells_pov(vl
,fp
);
570 /** Computes all Voronoi cells and saves the output in POV-Ray
572 * \param[in] filename the name of the file to write to. */
573 inline void draw_cells_pov(const char *filename
) {
574 FILE *fp(safe_fopen(filename
,"w"));
578 /** Computes the Voronoi cells and saves customized information
580 * \param[in] vl the loop class to use.
581 * \param[in] format the custom output string to use.
582 * \param[in] fp a file handle to write to. */
583 template<class c_loop
>
584 void print_custom(c_loop
&vl
,const char *format
,FILE *fp
) {
585 int ijk
,q
;double *pp
;
586 if(contains_neighbor(format
)) {
587 voronoicell_neighbor
c(*this);
588 if(vl
.start()) do if(compute_cell(c
,vl
)) {
589 ijk
=vl
.ijk
;q
=vl
.q
;pp
=p
[ijk
]+ps
*q
;
590 c
.output_custom(format
,id
[ijk
][q
],*pp
,pp
[1],pp
[2],pp
[3],fp
);
593 voronoicell
c(*this);
594 if(vl
.start()) do if(compute_cell(c
,vl
)) {
595 ijk
=vl
.ijk
;q
=vl
.q
;pp
=p
[ijk
]+ps
*q
;
596 c
.output_custom(format
,id
[ijk
][q
],*pp
,pp
[1],pp
[2],pp
[3],fp
);
600 /** Computes the Voronoi cell for a particle currently being
601 * referenced by a loop class.
602 * \param[out] c a Voronoi cell class in which to store the
604 * \param[in] vl the loop class to use.
605 * \return True if the cell was computed. If the cell cannot be
606 * computed because it was removed entirely for some reason,
607 * then the routine returns false. */
608 template<class v_cell
,class c_loop
>
609 inline bool compute_cell(v_cell
&c
,c_loop
&vl
) {
610 return vc
.compute_cell(c
,vl
.ijk
,vl
.q
,vl
.i
,vl
.j
,vl
.k
);
612 /** Computes the Voronoi cell for given particle.
613 * \param[out] c a Voronoi cell class in which to store the
615 * \param[in] ijk the block that the particle is within.
616 * \param[in] q the index of the particle within the block.
617 * \return True if the cell was computed. If the cell cannot be
618 * computed because it was removed entirely for some reason,
619 * then the routine returns false. */
620 template<class v_cell
>
621 inline bool compute_cell(v_cell
&c
,int ijk
,int q
) {
622 int k(ijk
/(nx
*oy
)),ijkt(ijk
-(nx
*oy
)*k
),j(ijkt
/nx
),i(ijkt
-j
*nx
);
623 return vc
.compute_cell(c
,ijk
,q
,i
,j
,k
);
625 /** Computes the Voronoi cell for a ghost particle at a given
627 * \param[out] c a Voronoi cell class in which to store the
629 * \param[in] (x,y,z) the location of the ghost particle.
630 * \param[in] r the radius of the ghost particle.
631 * \return True if the cell was computed. If the cell cannot be
632 * computed, if it is removed entirely by a wall or boundary
633 * condition, then the routine returns false. */
634 template<class v_cell
>
635 inline bool compute_ghost_cell(v_cell
&c
,double x
,double y
,double z
,double r
) {
637 put_locate_block(ijk
,x
,y
,z
);
638 double *pp
=p
[ijk
]+4*co
[ijk
]++,tm
=max_radius
;
639 *(pp
++)=x
;*(pp
++)=y
;*(pp
++)=z
;*pp
=r
;
640 if(r
>max_radius
) max_radius
=r
;
641 bool q
=compute_cell(c
,ijk
,co
[ijk
]-1);
642 co
[ijk
]--;max_radius
=tm
;
645 void print_custom(const char *format
,FILE *fp
=stdout
);
646 void print_custom(const char *format
,const char *filename
);
647 bool find_voronoi_cell(double x
,double y
,double z
,double &rx
,double &ry
,double &rz
,int &pid
);
649 voro_compute
<container_periodic_poly
> vc
;
650 friend class voro_compute
<container_periodic_poly
>;