Voro++
|
00001 // Voro++, a 3D cell-based Voronoi library 00002 // 00003 // Author : Chris H. Rycroft (LBL / UC Berkeley) 00004 // Email : chr@alum.mit.edu 00005 // Date : August 30th 2011 00006 00007 /** \file v_compute.hh 00008 * \brief Header file for the container_base template and related classes. */ 00009 00010 #ifndef VOROPP_V_COMPUTE_HH 00011 #define VOROPP_V_COMPUTE_HH 00012 00013 #include <cstdio> 00014 #include <cstdlib> 00015 #include <cmath> 00016 #include <vector> 00017 using namespace std; 00018 00019 #include "config.hh" 00020 #include "worklist.hh" 00021 #include "cell.hh" 00022 00023 namespace voro { 00024 00025 /** \brief Structure for holding information about a particle. 00026 * 00027 * This small structure holds information about a single particle, and is used 00028 * by several of the routines in the voro_compute template for passing 00029 * information by reference between functions. */ 00030 struct particle_record { 00031 /** The index of the block that the particle is within. */ 00032 int ijk; 00033 /** The number of particle within its block. */ 00034 int l; 00035 /** The x-index of the block. */ 00036 int di; 00037 /** The y-index of the block. */ 00038 int dj; 00039 /** The z-index of the block. */ 00040 int dk; 00041 }; 00042 00043 /** \brief Template for carrying out Voronoi cell computations. */ 00044 template <class c_class> 00045 class voro_compute { 00046 public: 00047 /** A reference to the container class on which to carry out*/ 00048 c_class &con; 00049 /** The size of an internal computational block in the x 00050 * direction. */ 00051 const double boxx; 00052 /** The size of an internal computational block in the y 00053 * direction. */ 00054 const double boxy; 00055 /** The size of an internal computational block in the z 00056 * direction. */ 00057 const double boxz; 00058 /** The inverse box length in the x direction, set to 00059 * nx/(bx-ax). */ 00060 const double xsp; 00061 /** The inverse box length in the y direction, set to 00062 * ny/(by-ay). */ 00063 const double ysp; 00064 /** The inverse box length in the z direction, set to 00065 * nz/(bz-az). */ 00066 const double zsp; 00067 /** The number of boxes in the x direction for the searching mask. */ 00068 const int hx; 00069 /** The number of boxes in the y direction for the searching mask. */ 00070 const int hy; 00071 /** The number of boxes in the z direction for the searching mask. */ 00072 const int hz; 00073 /** A constant, set to the value of hx multiplied by hy, which 00074 * is used in the routines which step through mask boxes in 00075 * sequence. */ 00076 const int hxy; 00077 /** A constant, set to the value of hx*hy*hz, which is used in 00078 * the routines which step through mask boxes in sequence. */ 00079 const int hxyz; 00080 /** The number of floating point entries to store for each 00081 * particle. */ 00082 const int ps; 00083 /** This array holds the numerical IDs of each particle in each 00084 * computational box. */ 00085 int **id; 00086 /** A two dimensional array holding particle positions. For the 00087 * derived container_poly class, this also holds particle 00088 * radii. */ 00089 double **p; 00090 /** An array holding the number of particles within each 00091 * computational box of the container. */ 00092 int *co; 00093 voro_compute(c_class &con_,int hx_,int hy_,int hz_); 00094 /** The class destructor frees the dynamically allocated memory 00095 * for the mask and queue. */ 00096 ~voro_compute() { 00097 delete [] qu; 00098 delete [] mask; 00099 } 00100 template<class v_cell> 00101 bool compute_cell(v_cell &c,int ijk,int s,int ci,int cj,int ck); 00102 void find_voronoi_cell(double x,double y,double z,int ci,int cj,int ck,int ijk,particle_record &w,double &mrs); 00103 private: 00104 /** A constant set to boxx*boxx+boxy*boxy+boxz*boxz, which is 00105 * frequently used in the computation. */ 00106 const double bxsq; 00107 /** This sets the current value being used to mark tested blocks 00108 * in the mask. */ 00109 unsigned int mv; 00110 /** The current size of the search list. */ 00111 int qu_size; 00112 /** A pointer to the array of worklists. */ 00113 const unsigned int *wl; 00114 /** An pointer to the array holding the minimum distances 00115 * associated with the worklists. */ 00116 double *mrad; 00117 /** This array is used during the cell computation to determine 00118 * which blocks have been considered. */ 00119 unsigned int *mask; 00120 /** An array is used to store the queue of blocks to test 00121 * during the Voronoi cell computation. */ 00122 int *qu; 00123 /** A pointer to the end of the queue array, used to determine 00124 * when the queue is full. */ 00125 int *qu_l; 00126 template<class v_cell> 00127 bool corner_test(v_cell &c,double xl,double yl,double zl,double xh,double yh,double zh); 00128 template<class v_cell> 00129 inline bool edge_x_test(v_cell &c,double x0,double yl,double zl,double x1,double yh,double zh); 00130 template<class v_cell> 00131 inline bool edge_y_test(v_cell &c,double xl,double y0,double zl,double xh,double y1,double zh); 00132 template<class v_cell> 00133 inline bool edge_z_test(v_cell &c,double xl,double yl,double z0,double xh,double yh,double z1); 00134 template<class v_cell> 00135 inline bool face_x_test(v_cell &c,double xl,double y0,double z0,double y1,double z1); 00136 template<class v_cell> 00137 inline bool face_y_test(v_cell &c,double x0,double yl,double z0,double x1,double z1); 00138 template<class v_cell> 00139 inline bool face_z_test(v_cell &c,double x0,double y0,double zl,double x1,double y1); 00140 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); 00141 bool compute_min_radius(int di,int dj,int dk,double fx,double fy,double fz,double mrs); 00142 inline void add_to_mask(int ei,int ej,int ek,int *&qu_e); 00143 inline void scan_bits_mask_add(unsigned int q,unsigned int *mijk,int ei,int ej,int ek,int *&qu_e); 00144 inline void scan_all(int ijk,double x,double y,double z,int di,int dj,int dk,particle_record &w,double &mrs); 00145 void add_list_memory(int*& qu_s,int*& qu_e); 00146 /** Resets the mask in cases where the mask counter wraps 00147 * around. */ 00148 inline void reset_mask() { 00149 for(unsigned int *mp(mask);mp<mask+hxyz;mp++) *mp=0; 00150 } 00151 }; 00152 00153 } 00154 00155 #endif