Voro++
v_base.cc
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_base.cc
00008  * \brief Function implementations for the base Voronoi container class. */
00009 
00010 #include "v_base.hh"
00011 #include "config.hh"
00012 
00013 namespace voro {
00014 
00015 /** This function is called during container construction. The routine scans
00016  * all of the worklists in the wl[] array. For a given worklist of blocks
00017  * labeled \f$w_1\f$ to \f$w_n\f$, it computes a sequence \f$r_0\f$ to
00018  * \f$r_n\f$ so that $r_i$ is the minimum distance to all the blocks
00019  * \f$w_{j}\f$ where \f$j>i\f$ and all blocks outside the worklist. The values
00020  * of \f$r_n\f$ is calculated first, as the minimum distance to any block in
00021  * the shell surrounding the worklist. The \f$r_i\f$ are then computed in
00022  * reverse order by considering the distance to \f$w_{i+1}\f$. */
00023 voro_base::voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_) :
00024         nx(nx_), ny(ny_), nz(nz_), nxy(nx_*ny_), nxyz(nxy*nz_), boxx(boxx_), boxy(boxy_), boxz(boxz_),
00025         xsp(1/boxx_), ysp(1/boxy_), zsp(1/boxz_), mrad(new double[wl_hgridcu*wl_seq_length]) {
00026         const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28;
00027         const double xstep=boxx/wl_fgrid,ystep=boxy/wl_fgrid,zstep=boxz/wl_fgrid;
00028         int i,j,k,lx,ly,lz,q;
00029         unsigned int f,*e=const_cast<unsigned int*> (wl);
00030         double xlo,ylo,zlo,xhi,yhi,zhi,minr,*radp=mrad;
00031         for(zlo=0,zhi=zstep,lz=0;lz<wl_hgrid;zlo=zhi,zhi+=zstep,lz++) {
00032                 for(ylo=0,yhi=ystep,ly=0;ly<wl_hgrid;ylo=yhi,yhi+=ystep,ly++) {
00033                         for(xlo=0,xhi=xstep,lx=0;lx<wl_hgrid;xlo=xhi,xhi+=xstep,lx++) {
00034                                 minr=large_number;
00035                                 for(q=e[0]+1;q<wl_seq_length;q++) {
00036                                         f=e[q];
00037                                         i=(f&127)-64;
00038                                         j=(f>>7&127)-64;
00039                                         k=(f>>14&127)-64;
00040                                         if((f&b2)==b2) {
00041                                                 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i-1,j,k);
00042                                                 if((f&b1)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
00043                                         } else if((f&b1)==b1) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
00044                                         if((f&b4)==b4) {
00045                                                 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j-1,k);
00046                                                 if((f&b3)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
00047                                         } else if((f&b3)==b3) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
00048                                         if((f&b6)==b6) {
00049                                                 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k-1);
00050                                                 if((f&b5)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
00051                                         } else if((f&b5)==b5) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
00052                                 }
00053                                 q--;
00054                                 while(q>0) {
00055                                         radp[q]=minr;
00056                                         f=e[q];
00057                                         i=(f&127)-64;
00058                                         j=(f>>7&127)-64;
00059                                         k=(f>>14&127)-64;
00060                                         compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k);
00061                                         q--;
00062                                 }
00063                                 *radp=minr;
00064                                 e+=wl_seq_length;
00065                                 radp+=wl_seq_length;
00066                         }
00067                 }
00068         }
00069 }
00070 
00071 /** Computes the minimum distance from a subregion to a given block. If this distance
00072  * is smaller than the value of minr, then it passes
00073  * \param[in,out] minr a pointer to the current minimum distance. If the distance
00074  *                     computed in this function is smaller, then this distance is
00075  *                     set to the new one.
00076  * \param[out] (xlo,ylo,zlo) the lower coordinates of the subregion being
00077  *                           considered.
00078  * \param[out] (xhi,yhi,zhi) the upper coordinates of the subregion being
00079  *                           considered.
00080  * \param[in] (ti,tj,tk) the coordinates of the block. */
00081 void voro_base::compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk) {
00082         double radsq,temp;
00083         if(ti>0) {temp=boxx*ti-xhi;radsq=temp*temp;}
00084         else if(ti<0) {temp=xlo-boxx*(1+ti);radsq=temp*temp;}
00085         else radsq=0;
00086 
00087         if(tj>0) {temp=boxy*tj-yhi;radsq+=temp*temp;}
00088         else if(tj<0) {temp=ylo-boxy*(1+tj);radsq+=temp*temp;}
00089 
00090         if(tk>0) {temp=boxz*tk-zhi;radsq+=temp*temp;}
00091         else if(tk<0) {temp=zlo-boxz*(1+tk);radsq+=temp*temp;}
00092 
00093         if(radsq<minr) minr=radsq;
00094 }
00095 
00096 /** Checks to see whether "%n" appears in a format sequence to determine
00097  * whether neighbor information is required or not.
00098  * \param[in] format the format string to check.
00099  * \return True if a "%n" is found, false otherwise. */
00100 bool voro_base::contains_neighbor(const char *format) {
00101         char *fmp=(const_cast<char*>(format));
00102 
00103         // Check to see if "%n" appears in the format sequence
00104         while(*fmp!=0) {
00105                 if(*fmp=='%') {
00106                         fmp++;
00107                         if(*fmp=='n') return true;
00108                         else if(*fmp==0) return false;
00109                 }
00110                 fmp++;
00111         }
00112 
00113         return false;
00114 }
00115 
00116 #include "v_base_wl.cc"
00117 
00118 }