Voro++
v_compute.hh
Go to the documentation of this file.
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 voro_compute 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