Voro++
container_prd.hh
Go to the documentation of this file.
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 : August 30th 2011
6 
7 /** \file container_prd.hh
8  * \brief Header file for the container_periodic_base and related classes. */
9 
10 #ifndef VOROPP_CONTAINER_PRD_HH
11 #define VOROPP_CONTAINER_PRD_HH
12 
13 #include <cstdio>
14 #include <vector>
15 
16 #include "config.hh"
17 #include "common.hh"
18 #include "v_base.hh"
19 #include "cell.hh"
20 #include "c_loops.hh"
21 #include "v_compute.hh"
22 #include "unitcell.hh"
23 #include "rad_option.hh"
24 
25 namespace voro {
26 
27 /** \brief Class for representing a particle system in a 3D periodic
28  * non-orthogonal periodic domain.
29  *
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.
39  *
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 {
44  public:
45  /** The lower y index (inclusive) of the primary domain within
46  * the block structure. */
47  int ey;
48  /** The lower z index (inclusive) of the primary domain within
49  * the block structure. */
50  int ez;
51  /** The upper y index (exclusive) of the primary domain within
52  * the block structure. */
53  int wy;
54  /** The upper z index (exclusive) of the primary domain within
55  * the block structure. */
56  int wz;
57  /** The total size of the block structure (including images) in
58  * the y direction. */
59  int oy;
60  /** The total size of the block structure (including images) in
61  * the z direction. */
62  int oz;
63  /** The total number of blocks. */
64  int oxyz;
65  /** This array holds the numerical IDs of each particle in each
66  * computational box. */
67  int **id;
68  /** A two dimensional array holding particle positions. For the
69  * derived container_poly class, this also holds particle
70  * radii. */
71  double **p;
72  /** This array holds the number of particles within each
73  * computational box of the container. */
74  int *co;
75  /** This array holds the maximum amount of particle memory for
76  * each computational box of the container. If the number of
77  * particles in a particular box ever approaches this limit,
78  * more is allocated using the add_particle_memory() function.
79  */
80  int *mem;
81  /** An array holding information about periodic image
82  * construction at a given location. */
83  char *img;
84  /** The initial amount of memory to allocate for particles
85  * for each block. */
86  const int init_mem;
87  /** The amount of memory in the array structure for each
88  * particle. This is set to 3 when the basic class is
89  * initialized, so that the array holds (x,y,z) positions. If
90  * the container class is initialized as part of the derived
91  * class container_poly, then this is set to 4, to also hold
92  * the particle radii. */
93  const int ps;
94  container_periodic_base(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_,
95  int nx_,int ny_,int nz_,int init_mem_,int ps);
97  /** Prints all particles in the container, including those that
98  * have been constructed in image blocks. */
99  inline void print_all_particles() {
100  int ijk,q;
101  for(ijk=0;ijk<oxyz;ijk++) for(q=0;q<co[ijk];q++)
102  printf("%d %g %g %g\n",id[ijk][q],p[ijk][ps*q],p[ijk][ps*q+1],p[ijk][ps*q+2]);
103  }
104  void region_count();
105  /** Initializes the Voronoi cell prior to a compute_cell
106  * operation for a specific particle being carried out by a
107  * voro_compute class. The cell is initialized to be the
108  * pre-computed unit Voronoi cell based on planes formed by
109  * periodic images of the particle.
110  * \param[in,out] c a reference to a voronoicell object.
111  * \param[in] ijk the block that the particle is within.
112  * \param[in] q the index of the particle within its block.
113  * \param[in] (ci,cj,ck) the coordinates of the block in the
114  * container coordinate system.
115  * \param[out] (i,j,k) the coordinates of the test block
116  * relative to the voro_compute
117  * coordinate system.
118  * \param[out] (x,y,z) the position of the particle.
119  * \param[out] disp a block displacement used internally by the
120  * compute_cell routine.
121  * \return False if the plane cuts applied by walls completely
122  * removed the cell, true otherwise. */
123  template<class v_cell>
124  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) {
125  c=unit_voro;
126  double *pp=p[ijk]+ps*q;
127  x=*(pp++);y=*(pp++);z=*pp;
128  i=nx;j=ey;k=ez;
129  return true;
130  }
131  /** Initializes parameters for a find_voronoi_cell call within
132  * the voro_compute template.
133  * \param[in] (ci,cj,ck) the coordinates of the test block in
134  * the container coordinate system.
135  * \param[in] ijk the index of the test block
136  * \param[out] (i,j,k) the coordinates of the test block
137  * relative to the voro_compute
138  * coordinate system.
139  * \param[out] disp a block displacement used internally by the
140  * find_voronoi_cell routine (but not needed
141  * in this instance.) */
142  inline void initialize_search(int ci,int cj,int ck,int ijk,int &i,int &j,int &k,int &disp) {
143  i=nx;j=ey;k=ez;
144  }
145  /** Returns the position of a particle currently being computed
146  * relative to the computational block that it is within. It is
147  * used to select the optimal worklist entry to use.
148  * \param[in] (x,y,z) the position of the particle.
149  * \param[in] (ci,cj,ck) the block that the particle is within.
150  * \param[out] (fx,fy,fz) the position relative to the block.
151  */
152  inline void frac_pos(double x,double y,double z,double ci,double cj,double ck,double &fx,double &fy,double &fz) {
153  fx=x-boxx*ci;
154  fy=y-boxy*(cj-ey);
155  fz=z-boxz*(ck-ez);
156  }
157  /** Calculates the index of block in the container structure
158  * corresponding to given coordinates.
159  * \param[in] (ci,cj,ck) the coordinates of the original block
160  * in the current computation, relative
161  * to the container coordinate system.
162  * \param[in] (ei,ej,ek) the displacement of the current block
163  * from the original block.
164  * \param[in,out] (qx,qy,qz) the periodic displacement that
165  * must be added to the particles
166  * within the computed block.
167  * \param[in] disp a block displacement used internally by the
168  * find_voronoi_cell and compute_cell routines
169  * (but not needed in this instance.)
170  * \return The block index. */
171  inline int region_index(int ci,int cj,int ck,int ei,int ej,int ek,double &qx,double &qy,double &qz,int &disp) {
172  int qi=ci+(ei-nx),qj=cj+(ej-ey),qk=ck+(ek-ez);
173  int iv(step_div(qi,nx));if(iv!=0) {qx=iv*bx;qi-=nx*iv;} else qx=0;
174  create_periodic_image(qi,qj,qk);
175  return qi+nx*(qj+oy*qk);
176  }
177  void create_all_images();
179  protected:
180  void add_particle_memory(int i);
181  void put_locate_block(int &ijk,double &x,double &y,double &z);
182  void put_locate_block(int &ijk,double &x,double &y,double &z,int &ai,int &aj,int &ak);
183  /** Creates particles within an image block by copying them
184  * from the primary domain and shifting them. If the given
185  * block is aligned with the primary domain in the z-direction,
186  * the routine calls the simpler create_side_image routine
187  * where the image block may comprise of particles from up to
188  * two primary blocks. Otherwise is calls the more complex
189  * create_vertical_image where the image block may comprise of
190  * particles from up to four primary blocks.
191  * \param[in] (di,dj,dk) the coordinates of the image block to
192  * create. */
193  inline void create_periodic_image(int di,int dj,int dk) {
194  if(di<0||di>=nx||dj<0||dj>=oy||dk<0||dk>=oz)
195  voro_fatal_error("Constructing periodic image for nonexistent point",VOROPP_INTERNAL_ERROR);
196  if(dk>=ez&&dk<wz) {
197  if(dj<ey||dj>=wy) create_side_image(di,dj,dk);
198  } else create_vertical_image(di,dj,dk);
199  }
200  void create_side_image(int di,int dj,int dk);
201  void create_vertical_image(int di,int dj,int dk);
202  void put_image(int reg,int fijk,int l,double dx,double dy,double dz);
203  inline void remap(int &ai,int &aj,int &ak,int &ci,int &cj,int &ck,double &x,double &y,double &z,int &ijk);
204 };
205 
206 /** \brief Extension of the container_periodic_base class for computing regular
207  * Voronoi tessellations.
208  *
209  * This class is an extension of the container_periodic_base that has routines
210  * specifically for computing the regular Voronoi tessellation with no
211  * dependence on particle radii. */
213  public:
214  container_periodic(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_,
215  int nx_,int ny_,int nz_,int init_mem_);
216  void clear();
217  void put(int n,double x,double y,double z);
218  void put(int n,double x,double y,double z,int &ai,int &aj,int &ak);
219  void put(particle_order &vo,int n,double x,double y,double z);
220  void import(FILE *fp=stdin);
221  void import(particle_order &vo,FILE *fp=stdin);
222  /** Imports a list of particles from an open file stream into
223  * the container. Entries of four numbers (Particle ID, x
224  * position, y position, z position) are searched for. If the
225  * file cannot be successfully read, then the routine causes a
226  * fatal error.
227  * \param[in] filename the name of the file to open and read
228  * from. */
229  inline void import(const char* filename) {
230  FILE *fp=safe_fopen(filename,"r");
231  import(fp);
232  fclose(fp);
233  }
234  /** Imports a list of particles from an open file stream into
235  * the container. Entries of four numbers (Particle ID, x
236  * position, y position, z position) are searched for. In
237  * addition, the order in which particles are read is saved
238  * into an ordering class. If the file cannot be successfully
239  * read, then the routine causes a fatal error.
240  * \param[in,out] vo the ordering class to use.
241  * \param[in] filename the name of the file to open and read
242  * from. */
243  inline void import(particle_order &vo,const char* filename) {
244  FILE *fp=safe_fopen(filename,"r");
245  import(vo,fp);
246  fclose(fp);
247  }
248  void compute_all_cells();
249  double sum_cell_volumes();
250  /** Dumps particle IDs and positions to a file.
251  * \param[in] vl the loop class to use.
252  * \param[in] fp a file handle to write to. */
253  template<class c_loop>
254  void draw_particles(c_loop &vl,FILE *fp) {
255  double *pp;
256  if(vl.start()) do {
257  pp=p[vl.ijk]+3*vl.q;
258  fprintf(fp,"%d %g %g %g\n",id[vl.ijk][vl.q],*pp,pp[1],pp[2]);
259  } while(vl.inc());
260  }
261  /** Dumps all of the particle IDs and positions to a file.
262  * \param[in] fp a file handle to write to. */
263  inline void draw_particles(FILE *fp=stdout) {
264  c_loop_all_periodic vl(*this);
265  draw_particles(vl,fp);
266  }
267  /** Dumps all of the particle IDs and positions to a file.
268  * \param[in] filename the name of the file to write to. */
269  inline void draw_particles(const char *filename) {
270  FILE *fp=safe_fopen(filename,"w");
271  draw_particles(fp);
272  fclose(fp);
273  }
274  /** Dumps particle positions in POV-Ray format.
275  * \param[in] vl the loop class to use.
276  * \param[in] fp a file handle to write to. */
277  template<class c_loop>
278  void draw_particles_pov(c_loop &vl,FILE *fp) {
279  double *pp;
280  if(vl.start()) do {
281  pp=p[vl.ijk]+3*vl.q;
282  fprintf(fp,"// id %d\nsphere{<%g,%g,%g>,s}\n",
283  id[vl.ijk][vl.q],*pp,pp[1],pp[2]);
284  } while(vl.inc());
285  }
286  /** Dumps all particle positions in POV-Ray format.
287  * \param[in] fp a file handle to write to. */
288  inline void draw_particles_pov(FILE *fp=stdout) {
289  c_loop_all_periodic vl(*this);
290  draw_particles_pov(vl,fp);
291  }
292  /** Dumps all particle positions in POV-Ray format.
293  * \param[in] filename the name of the file to write to. */
294  inline void draw_particles_pov(const char *filename) {
295  FILE *fp=safe_fopen(filename,"w");
296  draw_particles_pov(fp);
297  fclose(fp);
298  }
299  /** Computes Voronoi cells and saves the output in gnuplot
300  * format.
301  * \param[in] vl the loop class to use.
302  * \param[in] fp a file handle to write to. */
303  template<class c_loop>
304  void draw_cells_gnuplot(c_loop &vl,FILE *fp) {
305  voronoicell c;double *pp;
306  if(vl.start()) do if(compute_cell(c,vl)) {
307  pp=p[vl.ijk]+ps*vl.q;
308  c.draw_gnuplot(*pp,pp[1],pp[2],fp);
309  } while(vl.inc());
310  }
311  /** Computes all Voronoi cells and saves the output in gnuplot
312  * format.
313  * \param[in] fp a file handle to write to. */
314  inline void draw_cells_gnuplot(FILE *fp=stdout) {
315  c_loop_all_periodic vl(*this);
316  draw_cells_gnuplot(vl,fp);
317  }
318  /** Compute all Voronoi cells and saves the output in gnuplot
319  * format.
320  * \param[in] filename the name of the file to write to. */
321  inline void draw_cells_gnuplot(const char *filename) {
322  FILE *fp=safe_fopen(filename,"w");
323  draw_cells_gnuplot(fp);
324  fclose(fp);
325  }
326  /** Computes Voronoi cells and saves the output in POV-Ray
327  * format.
328  * \param[in] vl the loop class to use.
329  * \param[in] fp a file handle to write to. */
330  template<class c_loop>
331  void draw_cells_pov(c_loop &vl,FILE *fp) {
332  voronoicell c;double *pp;
333  if(vl.start()) do if(compute_cell(c,vl)) {
334  fprintf(fp,"// cell %d\n",id[vl.ijk][vl.q]);
335  pp=p[vl.ijk]+ps*vl.q;
336  c.draw_pov(*pp,pp[1],pp[2],fp);
337  } while(vl.inc());
338  }
339  /** Computes all Voronoi cells and saves the output in POV-Ray
340  * format.
341  * \param[in] fp a file handle to write to. */
342  inline void draw_cells_pov(FILE *fp=stdout) {
343  c_loop_all_periodic vl(*this);
344  draw_cells_pov(vl,fp);
345  }
346  /** Computes all Voronoi cells and saves the output in POV-Ray
347  * format.
348  * \param[in] filename the name of the file to write to. */
349  inline void draw_cells_pov(const char *filename) {
350  FILE *fp=safe_fopen(filename,"w");
351  draw_cells_pov(fp);
352  fclose(fp);
353  }
354  /** Computes the Voronoi cells and saves customized information
355  * about them.
356  * \param[in] vl the loop class to use.
357  * \param[in] format the custom output string to use.
358  * \param[in] fp a file handle to write to. */
359  template<class c_loop>
360  void print_custom(c_loop &vl,const char *format,FILE *fp) {
361  int ijk,q;double *pp;
362  if(contains_neighbor(format)) {
364  if(vl.start()) do if(compute_cell(c,vl)) {
365  ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q;
366  c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],default_radius,fp);
367  } while(vl.inc());
368  } else {
369  voronoicell c;
370  if(vl.start()) do if(compute_cell(c,vl)) {
371  ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q;
372  c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],default_radius,fp);
373  } while(vl.inc());
374  }
375  }
376  void print_custom(const char *format,FILE *fp=stdout);
377  void print_custom(const char *format,const char *filename);
378  bool find_voronoi_cell(double x,double y,double z,double &rx,double &ry,double &rz,int &pid);
379  /** Computes the Voronoi cell for a particle currently being
380  * referenced by a loop class.
381  * \param[out] c a Voronoi cell class in which to store the
382  * computed cell.
383  * \param[in] vl the loop class to use.
384  * \return True if the cell was computed. If the cell cannot be
385  * computed because it was removed entirely for some reason,
386  * then the routine returns false. */
387  template<class v_cell,class c_loop>
388  inline bool compute_cell(v_cell &c,c_loop &vl) {
389  return vc.compute_cell(c,vl.ijk,vl.q,vl.i,vl.j,vl.k);
390  }
391  /** Computes the Voronoi cell for given particle.
392  * \param[out] c a Voronoi cell class in which to store the
393  * computed cell.
394  * \param[in] ijk the block that the particle is within.
395  * \param[in] q the index of the particle within the block.
396  * \return True if the cell was computed. If the cell cannot be
397  * computed because it was removed entirely for some reason,
398  * then the routine returns false. */
399  template<class v_cell>
400  inline bool compute_cell(v_cell &c,int ijk,int q) {
401  int k(ijk/(nx*oy)),ijkt(ijk-(nx*oy)*k),j(ijkt/nx),i(ijkt-j*nx);
402  return vc.compute_cell(c,ijk,q,i,j,k);
403  }
404  /** Computes the Voronoi cell for a ghost particle at a given
405  * location.
406  * \param[out] c a Voronoi cell class in which to store the
407  * computed cell.
408  * \param[in] (x,y,z) the location of the ghost particle.
409  * \return True if the cell was computed. If the cell cannot be
410  * computed, if it is removed entirely by a wall or boundary
411  * condition, then the routine returns false. */
412  template<class v_cell>
413  inline bool compute_ghost_cell(v_cell &c,double x,double y,double z) {
414  int ijk;
415  put_locate_block(ijk,x,y,z);
416  double *pp=p[ijk]+3*co[ijk]++;
417  *(pp++)=x;*(pp++)=y;*(pp++)=z;
418  bool q=compute_cell(c,ijk,co[ijk]-1);
419  co[ijk]--;
420  return q;
421  }
422  private:
424  friend class voro_compute<container_periodic>;
425 };
426 
427 /** \brief Extension of the container_periodic_base class for computing radical
428  * Voronoi tessellations.
429  *
430  * This class is an extension of container_periodic_base that has routines
431  * specifically for computing the radical Voronoi tessellation that depends
432  * on the particle radii. */
434  public:
435  container_periodic_poly(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_,
436  int nx_,int ny_,int nz_,int init_mem_);
437  void clear();
438  void put(int n,double x,double y,double z,double r);
439  void put(int n,double x,double y,double z,double r,int &ai,int &aj,int &ak);
440  void put(particle_order &vo,int n,double x,double y,double z,double r);
441  void import(FILE *fp=stdin);
442  void import(particle_order &vo,FILE *fp=stdin);
443  /** Imports a list of particles from an open file stream into
444  * the container_poly class. Entries of five numbers (Particle
445  * ID, x position, y position, z position, radius) are searched
446  * for. If the file cannot be successfully read, then the
447  * routine causes a fatal error.
448  * \param[in] filename the name of the file to open and read
449  * from. */
450  inline void import(const char* filename) {
451  FILE *fp=safe_fopen(filename,"r");
452  import(fp);
453  fclose(fp);
454  }
455  /** Imports a list of particles from an open file stream into
456  * the container_poly class. Entries of five numbers (Particle
457  * ID, x position, y position, z position, radius) are searched
458  * for. In addition, the order in which particles are read is
459  * saved into an ordering class. If the file cannot be
460  * successfully read, then the routine causes a fatal error.
461  * \param[in,out] vo the ordering class to use.
462  * \param[in] filename the name of the file to open and read
463  * from. */
464  inline void import(particle_order &vo,const char* filename) {
465  FILE *fp=safe_fopen(filename,"r");
466  import(vo,fp);
467  fclose(fp);
468  }
469  void compute_all_cells();
470  double sum_cell_volumes();
471  /** Dumps particle IDs, positions and radii to a file.
472  * \param[in] vl the loop class to use.
473  * \param[in] fp a file handle to write to. */
474  template<class c_loop>
475  void draw_particles(c_loop &vl,FILE *fp) {
476  double *pp;
477  if(vl.start()) do {
478  pp=p[vl.ijk]+4*vl.q;
479  fprintf(fp,"%d %g %g %g %g\n",id[vl.ijk][vl.q],*pp,pp[1],pp[2],pp[3]);
480  } while(vl.inc());
481  }
482  /** Dumps all of the particle IDs, positions and radii to a
483  * file.
484  * \param[in] fp a file handle to write to. */
485  inline void draw_particles(FILE *fp=stdout) {
486  c_loop_all_periodic vl(*this);
487  draw_particles(vl,fp);
488  }
489  /** Dumps all of the particle IDs, positions and radii to a
490  * file.
491  * \param[in] filename the name of the file to write to. */
492  inline void draw_particles(const char *filename) {
493  FILE *fp=safe_fopen(filename,"w");
494  draw_particles(fp);
495  fclose(fp);
496  }
497  /** Dumps particle positions in POV-Ray format.
498  * \param[in] vl the loop class to use.
499  * \param[in] fp a file handle to write to. */
500  template<class c_loop>
501  void draw_particles_pov(c_loop &vl,FILE *fp) {
502  double *pp;
503  if(vl.start()) do {
504  pp=p[vl.ijk]+4*vl.q;
505  fprintf(fp,"// id %d\nsphere{<%g,%g,%g>,%g}\n",
506  id[vl.ijk][vl.q],*pp,pp[1],pp[2],pp[3]);
507  } while(vl.inc());
508  }
509  /** Dumps all the particle positions in POV-Ray format.
510  * \param[in] fp a file handle to write to. */
511  inline void draw_particles_pov(FILE *fp=stdout) {
512  c_loop_all_periodic vl(*this);
513  draw_particles_pov(vl,fp);
514  }
515  /** Dumps all the particle positions in POV-Ray format.
516  * \param[in] filename the name of the file to write to. */
517  inline void draw_particles_pov(const char *filename) {
518  FILE *fp(safe_fopen(filename,"w"));
519  draw_particles_pov(fp);
520  fclose(fp);
521  }
522  /** Computes Voronoi cells and saves the output in gnuplot
523  * format.
524  * \param[in] vl the loop class to use.
525  * \param[in] fp a file handle to write to. */
526  template<class c_loop>
527  void draw_cells_gnuplot(c_loop &vl,FILE *fp) {
528  voronoicell c;double *pp;
529  if(vl.start()) do if(compute_cell(c,vl)) {
530  pp=p[vl.ijk]+ps*vl.q;
531  c.draw_gnuplot(*pp,pp[1],pp[2],fp);
532  } while(vl.inc());
533  }
534  /** Compute all Voronoi cells and saves the output in gnuplot
535  * format.
536  * \param[in] fp a file handle to write to. */
537  inline void draw_cells_gnuplot(FILE *fp=stdout) {
538  c_loop_all_periodic vl(*this);
539  draw_cells_gnuplot(vl,fp);
540  }
541  /** Compute all Voronoi cells and saves the output in gnuplot
542  * format.
543  * \param[in] filename the name of the file to write to. */
544  inline void draw_cells_gnuplot(const char *filename) {
545  FILE *fp(safe_fopen(filename,"w"));
546  draw_cells_gnuplot(fp);
547  fclose(fp);
548  }
549  /** Computes Voronoi cells and saves the output in POV-Ray
550  * format.
551  * \param[in] vl the loop class to use.
552  * \param[in] fp a file handle to write to. */
553  template<class c_loop>
554  void draw_cells_pov(c_loop &vl,FILE *fp) {
555  voronoicell c;double *pp;
556  if(vl.start()) do if(compute_cell(c,vl)) {
557  fprintf(fp,"// cell %d\n",id[vl.ijk][vl.q]);
558  pp=p[vl.ijk]+ps*vl.q;
559  c.draw_pov(*pp,pp[1],pp[2],fp);
560  } while(vl.inc());
561  }
562  /** Computes all Voronoi cells and saves the output in POV-Ray
563  * format.
564  * \param[in] fp a file handle to write to. */
565  inline void draw_cells_pov(FILE *fp=stdout) {
566  c_loop_all_periodic vl(*this);
567  draw_cells_pov(vl,fp);
568  }
569  /** Computes all Voronoi cells and saves the output in POV-Ray
570  * format.
571  * \param[in] filename the name of the file to write to. */
572  inline void draw_cells_pov(const char *filename) {
573  FILE *fp(safe_fopen(filename,"w"));
574  draw_cells_pov(fp);
575  fclose(fp);
576  }
577  /** Computes the Voronoi cells and saves customized information
578  * about them.
579  * \param[in] vl the loop class to use.
580  * \param[in] format the custom output string to use.
581  * \param[in] fp a file handle to write to. */
582  template<class c_loop>
583  void print_custom(c_loop &vl,const char *format,FILE *fp) {
584  int ijk,q;double *pp;
585  if(contains_neighbor(format)) {
587  if(vl.start()) do if(compute_cell(c,vl)) {
588  ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q;
589  c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],pp[3],fp);
590  } while(vl.inc());
591  } else {
592  voronoicell c;
593  if(vl.start()) do if(compute_cell(c,vl)) {
594  ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q;
595  c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],pp[3],fp);
596  } while(vl.inc());
597  }
598  }
599  /** Computes the Voronoi cell for a particle currently being
600  * referenced by a loop class.
601  * \param[out] c a Voronoi cell class in which to store the
602  * computed cell.
603  * \param[in] vl the loop class to use.
604  * \return True if the cell was computed. If the cell cannot be
605  * computed because it was removed entirely for some reason,
606  * then the routine returns false. */
607  template<class v_cell,class c_loop>
608  inline bool compute_cell(v_cell &c,c_loop &vl) {
609  return vc.compute_cell(c,vl.ijk,vl.q,vl.i,vl.j,vl.k);
610  }
611  /** Computes the Voronoi cell for given particle.
612  * \param[out] c a Voronoi cell class in which to store the
613  * computed cell.
614  * \param[in] ijk the block that the particle is within.
615  * \param[in] q the index of the particle within the block.
616  * \return True if the cell was computed. If the cell cannot be
617  * computed because it was removed entirely for some reason,
618  * then the routine returns false. */
619  template<class v_cell>
620  inline bool compute_cell(v_cell &c,int ijk,int q) {
621  int k(ijk/(nx*oy)),ijkt(ijk-(nx*oy)*k),j(ijkt/nx),i(ijkt-j*nx);
622  return vc.compute_cell(c,ijk,q,i,j,k);
623  }
624  /** Computes the Voronoi cell for a ghost particle at a given
625  * location.
626  * \param[out] c a Voronoi cell class in which to store the
627  * computed cell.
628  * \param[in] (x,y,z) the location of the ghost particle.
629  * \param[in] r the radius of the ghost particle.
630  * \return True if the cell was computed. If the cell cannot be
631  * computed, if it is removed entirely by a wall or boundary
632  * condition, then the routine returns false. */
633  template<class v_cell>
634  inline bool compute_ghost_cell(v_cell &c,double x,double y,double z,double r) {
635  int ijk;
636  put_locate_block(ijk,x,y,z);
637  double *pp=p[ijk]+4*co[ijk]++,tm=max_radius;
638  *(pp++)=x;*(pp++)=y;*(pp++)=z;*pp=r;
639  if(r>max_radius) max_radius=r;
640  bool q=compute_cell(c,ijk,co[ijk]-1);
641  co[ijk]--;max_radius=tm;
642  return q;
643  }
644  void print_custom(const char *format,FILE *fp=stdout);
645  void print_custom(const char *format,const char *filename);
646  bool find_voronoi_cell(double x,double y,double z,double &rx,double &ry,double &rz,int &pid);
647  private:
650 };
651 
652 }
653 
654 #endif
const double bx
Definition: unitcell.hh:26
Extension of the voronoicell_base class to represent a Voronoi cell with neighbor information...
Definition: cell.hh:403
void create_vertical_image(int di, int dj, int dk)
bool find_voronoi_cell(double x, double y, double z, double &rx, double &ry, double &rz, int &pid)
container_periodic_poly(double bx_, double bxy_, double by_, double bxz_, double byz_, double bz_, int nx_, int ny_, int nz_, int init_mem_)
void draw_cells_gnuplot(const char *filename)
Extension of the container_periodic_base class for computing radical Voronoi tessellations.
void draw_gnuplot(double x, double y, double z, FILE *fp=stdout)
Definition: cell.cc:1507
void initialize_search(int ci, int cj, int ck, int ijk, int &i, int &j, int &k, int &disp)
Class containing all of the routines that are specific to computing the radical Voronoi tessellation...
Definition: rad_option.hh:82
void draw_particles_pov(c_loop &vl, FILE *fp)
Header file for the classes encapsulating functionality for the regular and radical Voronoi tessellat...
void draw_cells_gnuplot(c_loop &vl, FILE *fp)
Header file for the loop classes.
Class containing data structures common across all particle container classes.
Definition: v_base.hh:25
const double boxy
Definition: v_base.hh:43
voronoicell unit_voro
Definition: unitcell.hh:44
void put_image(int reg, int fijk, int l, double dx, double dy, double dz)
void draw_particles_pov(FILE *fp=stdout)
Header file for the voronoicell and related classes.
Master configuration file for setting various compile-time options.
void put(int n, double x, double y, double z, double r)
bool find_voronoi_cell(double x, double y, double z, double &rx, double &ry, double &rz, int &pid)
void draw_cells_pov(const char *filename)
Header file for the voro_compute template and related classes.
Class for computation of the unit Voronoi cell associated with a 3D non-rectangular periodic domain...
Definition: unitcell.hh:22
void create_side_image(int di, int dj, int dk)
#define VOROPP_INTERNAL_ERROR
Definition: config.hh:119
void put(int n, double x, double y, double z)
void create_periodic_image(int di, int dj, int dk)
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)
container_periodic(double bx_, double bxy_, double by_, double bxz_, double byz_, double bz_, int nx_, int ny_, int nz_, int init_mem_)
void draw_cells_pov(FILE *fp=stdout)
Header file for the unitcell class.
void draw_cells_pov(c_loop &vl, FILE *fp)
void draw_particles(const char *filename)
bool contains_neighbor(const char *format)
Definition: v_base.cc:100
int step_div(int a, int b)
Definition: v_base.hh:81
Extension of the container_periodic_base class for computing regular Voronoi tessellations.
bool compute_cell(v_cell &c, int ijk, int q)
void draw_cells_pov(const char *filename)
void draw_pov(double x, double y, double z, FILE *fp=stdout)
Definition: cell.cc:1487
void draw_cells_gnuplot(FILE *fp=stdout)
void print_custom(c_loop &vl, const char *format, FILE *fp)
bool compute_cell(v_cell &c, c_loop &vl)
const double boxx
Definition: v_base.hh:41
void draw_cells_gnuplot(FILE *fp=stdout)
void draw_particles(c_loop &vl, FILE *fp)
void draw_particles_pov(const char *filename)
int region_index(int ci, int cj, int ck, int ei, int ej, int ek, double &qx, double &qy, double &qz, int &disp)
void draw_cells_gnuplot(c_loop &vl, FILE *fp)
container_periodic_base(double bx_, double bxy_, double by_, double bxz_, double byz_, double bz_, int nx_, int ny_, int nz_, int init_mem_, int ps)
const double boxz
Definition: v_base.hh:45
Header file for the base Voronoi container class.
void draw_particles(FILE *fp=stdout)
void draw_cells_pov(FILE *fp=stdout)
bool compute_ghost_cell(v_cell &c, double x, double y, double z, double r)
Header file for the small helper functions.
void draw_particles(c_loop &vl, FILE *fp)
void draw_particles_pov(const char *filename)
void put_locate_block(int &ijk, double &x, double &y, double &z)
void remap(int &ai, int &aj, int &ak, int &ci, int &cj, int &ck, double &x, double &y, double &z, int &ijk)
void draw_particles(const char *filename)
void output_custom(const char *format, FILE *fp=stdout)
Definition: cell.hh:182
Extension of the voronoicell_base class to represent a Voronoi cell without neighbor information...
Definition: cell.hh:300
Template for carrying out Voronoi cell computations.
Definition: v_compute.hh:39
void draw_particles(FILE *fp=stdout)
void draw_cells_gnuplot(const char *filename)
A class for looping over all particles in a container_periodic or container_periodic_poly class...
Definition: c_loops.hh:325
bool compute_cell(v_cell &c, c_loop &vl)
bool compute_ghost_cell(v_cell &c, double x, double y, double z)
bool compute_cell(v_cell &c, int ijk, int q)
void draw_particles_pov(FILE *fp=stdout)
A class for storing ordering information when particles are added to a container. ...
Definition: c_loops.hh:37
void frac_pos(double x, double y, double z, double ci, double cj, double ck, double &fx, double &fy, double &fz)
void draw_particles_pov(c_loop &vl, FILE *fp)
void print_custom(c_loop &vl, const char *format, FILE *fp)
void draw_cells_pov(c_loop &vl, FILE *fp)
Class containing all of the routines that are specific to computing the regular Voronoi tessellation...
Definition: rad_option.hh:24
Class for representing a particle system in a 3D periodic non-orthogonal periodic domain...
const int nx
Definition: v_base.hh:28