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 wall.cc 00008 * \brief Function implementations for the derived wall classes. */ 00009 00010 #include "wall.hh" 00011 00012 namespace voro { 00013 00014 /** Tests to see whether a point is inside the sphere wall object. 00015 * \param[in,out] (x,y,z) the vector to test. 00016 * \return True if the point is inside, false if the point is outside. */ 00017 bool wall_sphere::point_inside(double x,double y,double z) { 00018 return (x-xc)*(x-xc)+(y-yc)*(y-yc)+(z-zc)*(z-zc)<rc*rc; 00019 } 00020 00021 /** Cuts a cell by the sphere wall object. The spherical wall is approximated by 00022 * a single plane applied at the point on the sphere which is closest to the center 00023 * of the cell. This works well for particle arrangements that are packed against 00024 * the wall, but loses accuracy for sparse particle distributions. 00025 * \param[in,out] c the Voronoi cell to be cut. 00026 * \param[in] (x,y,z) the location of the Voronoi cell. 00027 * \return True if the cell still exists, false if the cell is deleted. */ 00028 template<class v_cell> 00029 bool wall_sphere::cut_cell_base(v_cell &c,double x,double y,double z) { 00030 double xd=x-xc,yd=y-yc,zd=z-zc,dq=xd*xd+yd*yd+zd*zd; 00031 if (dq>1e-5) { 00032 dq=2*(sqrt(dq)*rc-dq); 00033 return c.nplane(xd,yd,zd,dq,w_id); 00034 } 00035 return true; 00036 } 00037 00038 /** Tests to see whether a point is inside the plane wall object. 00039 * \param[in] (x,y,z) the vector to test. 00040 * \return True if the point is inside, false if the point is outside. */ 00041 bool wall_plane::point_inside(double x,double y,double z) { 00042 return x*xc+y*yc+z*zc<ac; 00043 } 00044 00045 /** Cuts a cell by the plane wall object. 00046 * \param[in,out] c the Voronoi cell to be cut. 00047 * \param[in] (x,y,z) the location of the Voronoi cell. 00048 * \return True if the cell still exists, false if the cell is deleted. */ 00049 template<class v_cell> 00050 bool wall_plane::cut_cell_base(v_cell &c,double x,double y,double z) { 00051 double dq=2*(ac-x*xc-y*yc-z*zc); 00052 return c.nplane(xc,yc,zc,dq,w_id); 00053 } 00054 00055 /** Tests to see whether a point is inside the cylindrical wall object. 00056 * \param[in] (x,y,z) the vector to test. 00057 * \return True if the point is inside, false if the point is outside. */ 00058 bool wall_cylinder::point_inside(double x,double y,double z) { 00059 double xd=x-xc,yd=y-yc,zd=z-zc; 00060 double pa=(xd*xa+yd*ya+zd*za)*asi; 00061 xd-=xa*pa;yd-=ya*pa;zd-=za*pa; 00062 return xd*xd+yd*yd+zd*zd<rc*rc; 00063 } 00064 00065 /** Cuts a cell by the cylindrical wall object. The cylindrical wall is 00066 * approximated by a single plane applied at the point on the cylinder which is 00067 * closest to the center of the cell. This works well for particle arrangements 00068 * that are packed against the wall, but loses accuracy for sparse particle 00069 * distributions. 00070 * \param[in,out] c the Voronoi cell to be cut. 00071 * \param[in] (x,y,z) the location of the Voronoi cell. 00072 * \return True if the cell still exists, false if the cell is deleted. */ 00073 template<class v_cell> 00074 bool wall_cylinder::cut_cell_base(v_cell &c,double x,double y,double z) { 00075 double xd=x-xc,yd=y-yc,zd=z-zc,pa=(xd*xa+yd*ya+zd*za)*asi; 00076 xd-=xa*pa;yd-=ya*pa;zd-=za*pa; 00077 pa=xd*xd+yd*yd+zd*zd; 00078 if(pa>1e-5) { 00079 pa=2*(sqrt(pa)*rc-pa); 00080 return c.nplane(xd,yd,zd,pa,w_id); 00081 } 00082 return true; 00083 } 00084 00085 /** Tests to see whether a point is inside the cone wall object. 00086 * \param[in] (x,y,z) the vector to test. 00087 * \return True if the point is inside, false if the point is outside. */ 00088 bool wall_cone::point_inside(double x,double y,double z) { 00089 double xd=x-xc,yd=y-yc,zd=z-zc,pa=(xd*xa+yd*ya+zd*za)*asi; 00090 xd-=xa*pa;yd-=ya*pa;zd-=za*pa; 00091 pa*=gra; 00092 if (pa<0) return false; 00093 pa*=pa; 00094 return xd*xd+yd*yd+zd*zd<pa; 00095 } 00096 00097 /** Cuts a cell by the cone wall object. The conical wall is 00098 * approximated by a single plane applied at the point on the cone which is 00099 * closest to the center of the cell. This works well for particle arrangements 00100 * that are packed against the wall, but loses accuracy for sparse particle 00101 * distributions. 00102 * \param[in,out] c the Voronoi cell to be cut. 00103 * \param[in] (x,y,z) the location of the Voronoi cell. 00104 * \return True if the cell still exists, false if the cell is deleted. */ 00105 template<class v_cell> 00106 bool wall_cone::cut_cell_base(v_cell &c,double x,double y,double z) { 00107 double xd=x-xc,yd=y-yc,zd=z-zc,xf,yf,zf,q,pa=(xd*xa+yd*ya+zd*za)*asi; 00108 xd-=xa*pa;yd-=ya*pa;zd-=za*pa; 00109 pa=xd*xd+yd*yd+zd*zd; 00110 if(pa>1e-5) { 00111 pa=1/sqrt(pa); 00112 q=sqrt(asi); 00113 xf=-sang*q*xa+cang*pa*xd; 00114 yf=-sang*q*ya+cang*pa*yd; 00115 zf=-sang*q*za+cang*pa*zd; 00116 pa=2*(xf*(xc-x)+yf*(yc-y)+zf*(zc-z)); 00117 return c.nplane(xf,yf,zf,pa,w_id); 00118 } 00119 return true; 00120 } 00121 00122 }