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 v_compute.hh 8 * \brief Header file for the voro_compute template and related classes. */ 9 10 #ifndef VOROPP_V_COMPUTE_HH 11 #define VOROPP_V_COMPUTE_HH 12 13 #include <cstdio> 14 #include <cstdlib> 15 #include <cmath> 16 #include <vector> 17 using namespace std; 18 19 #include "config.hh" 20 #include "worklist.hh" 21 #include "cell.hh" 22 23 namespace voro { 24 25 /** \brief Structure for holding information about a particle. 26 * 27 * This small structure holds information about a single particle, and is used 28 * by several of the routines in the voro_compute template for passing 29 * information by reference between functions. */ 30 struct particle_record { 31 /** The index of the block that the particle is within. */ 32 int ijk; 33 /** The number of particle within its block. */ 34 int l; 35 /** The x-index of the block. */ 36 int di; 37 /** The y-index of the block. */ 38 int dj; 39 /** The z-index of the block. */ 40 int dk; 41 }; 42 43 /** \brief Template for carrying out Voronoi cell computations. */ 44 template <class c_class> 45 class voro_compute { 46 public: 47 /** A reference to the container class on which to carry out*/ 48 c_class &con; 49 /** The size of an internal computational block in the x 50 * direction. */ 51 const double boxx; 52 /** The size of an internal computational block in the y 53 * direction. */ 54 const double boxy; 55 /** The size of an internal computational block in the z 56 * direction. */ 57 const double boxz; 58 /** The inverse box length in the x direction, set to 59 * nx/(bx-ax). */ 60 const double xsp; 61 /** The inverse box length in the y direction, set to 62 * ny/(by-ay). */ 63 const double ysp; 64 /** The inverse box length in the z direction, set to 65 * nz/(bz-az). */ 66 const double zsp; 67 /** The number of boxes in the x direction for the searching mask. */ 68 const int hx; 69 /** The number of boxes in the y direction for the searching mask. */ 70 const int hy; 71 /** The number of boxes in the z direction for the searching mask. */ 72 const int hz; 73 /** A constant, set to the value of hx multiplied by hy, which 74 * is used in the routines which step through mask boxes in 75 * sequence. */ 76 const int hxy; 77 /** A constant, set to the value of hx*hy*hz, which is used in 78 * the routines which step through mask boxes in sequence. */ 79 const int hxyz; 80 /** The number of floating point entries to store for each 81 * particle. */ 82 const int ps; 83 /** This array holds the numerical IDs of each particle in each 84 * computational box. */ 85 int **id; 86 /** A two dimensional array holding particle positions. For the 87 * derived container_poly class, this also holds particle 88 * radii. */ 89 double **p; 90 /** An array holding the number of particles within each 91 * computational box of the container. */ 92 int *co; 93 voro_compute(c_class &con_,int hx_,int hy_,int hz_); 94 /** The class destructor frees the dynamically allocated memory 95 * for the mask and queue. */ ~voro_compute()96 ~voro_compute() { 97 delete [] qu; 98 delete [] mask; 99 } 100 template<class v_cell> 101 bool compute_cell(v_cell &c,int ijk,int s,int ci,int cj,int ck); 102 void find_voronoi_cell(double x,double y,double z,int ci,int cj,int ck,int ijk,particle_record &w,double &mrs); 103 private: 104 /** A constant set to boxx*boxx+boxy*boxy+boxz*boxz, which is 105 * frequently used in the computation. */ 106 const double bxsq; 107 /** This sets the current value being used to mark tested blocks 108 * in the mask. */ 109 unsigned int mv; 110 /** The current size of the search list. */ 111 int qu_size; 112 /** A pointer to the array of worklists. */ 113 const unsigned int *wl; 114 /** An pointer to the array holding the minimum distances 115 * associated with the worklists. */ 116 double *mrad; 117 /** This array is used during the cell computation to determine 118 * which blocks have been considered. */ 119 unsigned int *mask; 120 /** An array is used to store the queue of blocks to test 121 * during the Voronoi cell computation. */ 122 int *qu; 123 /** A pointer to the end of the queue array, used to determine 124 * when the queue is full. */ 125 int *qu_l; 126 template<class v_cell> 127 bool corner_test(v_cell &c,double xl,double yl,double zl,double xh,double yh,double zh); 128 template<class v_cell> 129 inline bool edge_x_test(v_cell &c,double x0,double yl,double zl,double x1,double yh,double zh); 130 template<class v_cell> 131 inline bool edge_y_test(v_cell &c,double xl,double y0,double zl,double xh,double y1,double zh); 132 template<class v_cell> 133 inline bool edge_z_test(v_cell &c,double xl,double yl,double z0,double xh,double yh,double z1); 134 template<class v_cell> 135 inline bool face_x_test(v_cell &c,double xl,double y0,double z0,double y1,double z1); 136 template<class v_cell> 137 inline bool face_y_test(v_cell &c,double x0,double yl,double z0,double x1,double z1); 138 template<class v_cell> 139 inline bool face_z_test(v_cell &c,double x0,double y0,double zl,double x1,double y1); 140 bool compute_min_max_radius(int di,int dj,int dk,double fx,double fy,double fz,double gx,double gy,double gz,double& crs,double mrs); 141 bool compute_min_radius(int di,int dj,int dk,double fx,double fy,double fz,double mrs); 142 inline void add_to_mask(int ei,int ej,int ek,int *&qu_e); 143 inline void scan_bits_mask_add(unsigned int q,unsigned int *mijk,int ei,int ej,int ek,int *&qu_e); 144 inline void scan_all(int ijk,double x,double y,double z,int di,int dj,int dk,particle_record &w,double &mrs); 145 void add_list_memory(int*& qu_s,int*& qu_e); 146 /** Resets the mask in cases where the mask counter wraps 147 * around. */ reset_mask()148 inline void reset_mask() { 149 for(unsigned int *mp(mask);mp<mask+hxyz;mp++) *mp=0; 150 } 151 }; 152 153 } 154 155 #endif 156