Voro++
c_loops.cc
Go to the documentation of this file.
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 c_loops.cc
8  * \brief Function implementations for the loop classes. */
9 
10 #include "c_loops.hh"
11 
12 namespace voro {
13 
14 /** Initializes a c_loop_subset object to scan over all particles within a
15  * given sphere.
16  * \param[in] (vx,vy,vz) the position vector of the center of the sphere.
17  * \param[in] r the radius of the sphere.
18  * \param[in] bounds_test whether to do detailed bounds checking. If this is
19  * false then the class will loop over all particles in
20  * blocks that overlap the given sphere. If it is true,
21  * the particle will only loop over the particles which
22  * actually lie within the sphere.
23  * \return True if there is any valid point to loop over, false otherwise. */
24 void c_loop_subset::setup_sphere(double vx,double vy,double vz,double r,bool bounds_test) {
25  if(bounds_test) {mode=sphere;v0=vx;v1=vy;v2=vz;v3=r*r;} else mode=no_check;
26  ai=step_int((vx-ax-r)*xsp);
27  bi=step_int((vx-ax+r)*xsp);
28  aj=step_int((vy-ay-r)*ysp);
29  bj=step_int((vy-ay+r)*ysp);
30  ak=step_int((vz-az-r)*zsp);
31  bk=step_int((vz-az+r)*zsp);
32  setup_common();
33 }
34 
35 /** Initializes the class to loop over all particles in a rectangular subgrid
36  * of blocks.
37  * \param[in] (ai_,bi_) the subgrid range in the x-direction, inclusive of both
38  * ends.
39  * \param[in] (aj_,bj_) the subgrid range in the y-direction, inclusive of both
40  * ends.
41  * \param[in] (ak_,bk_) the subgrid range in the z-direction, inclusive of both
42  * ends.
43  * \return True if there is any valid point to loop over, false otherwise. */
44 void c_loop_subset::setup_intbox(int ai_,int bi_,int aj_,int bj_,int ak_,int bk_) {
45  ai=ai_;bi=bi_;aj=aj_;bj=bj_;ak=ak_;bk=bk_;
46  mode=no_check;
47  setup_common();
48 }
49 
50 /** Sets up all of the common constants used for the loop.
51  * \return True if there is any valid point to loop over, false otherwise. */
52 void c_loop_subset::setup_common() {
53  if(!xperiodic) {
54  if(ai<0) {ai=0;if(bi<0) bi=0;}
55  if(bi>=nx) {bi=nx-1;if(ai>=nx) ai=nx-1;}
56  }
57  if(!yperiodic) {
58  if(aj<0) {aj=0;if(bj<0) bj=0;}
59  if(bj>=ny) {bj=ny-1;if(aj>=ny) aj=ny-1;}
60  }
61  if(!zperiodic) {
62  if(ak<0) {ak=0;if(bk<0) bk=0;}
63  if(bk>=nz) {bk=nz-1;if(ak>=nz) ak=nz-1;}
64  }
65  ci=ai;cj=aj;ck=ak;
66  di=i=step_mod(ci,nx);apx=px=step_div(ci,nx)*sx;
67  dj=j=step_mod(cj,ny);apy=py=step_div(cj,ny)*sy;
68  dk=k=step_mod(ck,nz);apz=pz=step_div(ck,nz)*sz;
69  inc1=di-step_mod(bi,nx);
70  inc2=nx*(ny+dj-step_mod(bj,ny))+inc1;
71  inc1+=nx;
72  ijk=di+nx*(dj+ny*dk);
73  q=0;
74 }
75 
76 /** Starts the loop by finding the first particle within the container to
77  * consider.
78  * \return True if there is any particle to consider, false otherwise. */
80  while(co[ijk]==0) {if(!next_block()) return false;}
81  while(mode!=no_check&&out_of_bounds()) {
82  q++;
83  while(q>=co[ijk]) {q=0;if(!next_block()) return false;}
84  }
85  return true;
86 }
87 
88 /** Initializes the class to loop over all particles in a rectangular box.
89  * \param[in] (xmin,xmax) the minimum and maximum x coordinates of the box.
90  * \param[in] (ymin,ymax) the minimum and maximum y coordinates of the box.
91  * \param[in] (zmin,zmax) the minimum and maximum z coordinates of the box.
92  * \param[in] bounds_test whether to do detailed bounds checking. If this is
93  * false then the class will loop over all particles in
94  * blocks that overlap the given box. If it is true, the
95  * particle will only loop over the particles which
96  * actually lie within the box.
97  * \return True if there is any valid point to loop over, false otherwise. */
98 void c_loop_subset::setup_box(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax,bool bounds_test) {
99  if(bounds_test) {mode=box;v0=xmin;v1=xmax;v2=ymin;v3=ymax;v4=zmin;v5=zmax;} else mode=no_check;
100  ai=step_int((xmin-ax)*xsp);
101  bi=step_int((xmax-ax)*xsp);
102  aj=step_int((ymin-ay)*ysp);
103  bj=step_int((ymax-ay)*ysp);
104  ak=step_int((zmin-az)*zsp);
105  bk=step_int((zmax-az)*zsp);
106  setup_common();
107 }
108 
109 /** Computes whether the current point is out of bounds, relative to the
110  * current loop setup.
111  * \return True if the point is out of bounds, false otherwise. */
112 bool c_loop_subset::out_of_bounds() {
113  double *pp=p[ijk]+ps*q;
114  if(mode==sphere) {
115  double fx(*pp+px-v0),fy(pp[1]+py-v1),fz(pp[2]+pz-v2);
116  return fx*fx+fy*fy+fz*fz>v3;
117  } else {
118  double f(*pp+px);if(f<v0||f>v1) return true;
119  f=pp[1]+py;if(f<v2||f>v3) return true;
120  f=pp[2]+pz;return f<v4||f>v5;
121  }
122 }
123 
124 /** Returns the next block to be tested in a loop, and updates the periodicity
125  * vector if necessary. */
126 bool c_loop_subset::next_block() {
127  if(i<bi) {
128  i++;
129  if(ci<nx-1) {ci++;ijk++;} else {ci=0;ijk+=1-nx;px+=sx;}
130  return true;
131  } else if(j<bj) {
132  i=ai;ci=di;px=apx;j++;
133  if(cj<ny-1) {cj++;ijk+=inc1;} else {cj=0;ijk+=inc1-nxy;py+=sy;}
134  return true;
135  } else if(k<bk) {
136  i=ai;ci=di;j=aj;cj=dj;px=apx;py=apy;k++;
137  if(ck<nz-1) {ck++;ijk+=inc2;} else {ck=0;ijk+=inc2-nxyz;pz+=sz;}
138  return true;
139  } else return false;
140 }
141 
142 /** Extends the memory available for storing the ordering. */
143 void particle_order::add_ordering_memory() {
144  int *no=new int[size<<2],*nop=no,*opp=o;
145  while(opp<op) *(nop++)=*(opp++);
146  delete [] o;
147  size<<=1;o=no;op=nop;
148 }
149 
150 }
const int ps
Definition: c_loops.hh:95
Header file for the loop classes.
const int nz
Definition: c_loops.hh:85
void setup_box(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax, bool bounds_test=true)
Definition: c_loops.cc:98
double ** p
Definition: c_loops.hh:98
const int nxyz
Definition: c_loops.hh:92
const int nx
Definition: c_loops.hh:81
c_loop_subset_mode mode
Definition: c_loops.hh:223
const int ny
Definition: c_loops.hh:83
void setup_intbox(int ai_, int bi_, int aj_, int bj_, int ak_, int bk_)
Definition: c_loops.cc:44
void setup_sphere(double vx, double vy, double vz, double r, bool bounds_test=true)
Definition: c_loops.cc:24
const int nxy
Definition: c_loops.hh:89