1 // Voro++, a 3D cell-based Voronoi library
3 // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email : chr@alum.mit.edu
5 // Date : August 30th 2011
7 /** \file c_loops_2d.cc
8 * \brief Function implementations for the 2D loop classes. */
10 #include "c_loops_2d.hh"
14 /** Initializes a c_loop_subset_2d object to scan over all particles within a
16 * \param[in] (vx,vy) the position vector of the center of the circle.
17 * \param[in] r the radius of the circle.
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 circle. If it is true,
21 * the particle will only loop over the particles which
22 * actually lie within the circle.
23 * \return True if there is any valid point to loop over, false otherwise. */
24 void c_loop_subset_2d::setup_circle(double vx
,double vy
,double r
,bool bounds_test
) {
25 if(bounds_test
) {mode
=circle
;v0
=vx
;v1
=vy
;v2
=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
);
33 /** Initializes the class to loop over all particles in a rectangular subgrid
35 * \param[in] (ai_,bi_) the subgrid range in the x-direction, inclusive of both
37 * \param[in] (aj_,bj_) the subgrid range in the y-direction, inclusive of both
39 * \return True if there is any valid point to loop over, false otherwise. */
40 void c_loop_subset_2d::setup_intbox(int ai_
,int bi_
,int aj_
,int bj_
) {
41 ai
=ai_
;bi
=bi_
;aj
=aj_
;bj
=bj_
;
46 /** Sets up all of the common constants used for the loop.
47 * \return True if there is any valid point to loop over, false otherwise. */
48 void c_loop_subset_2d::setup_common() {
50 if(ai
<0) {ai
=0;if(bi
<0) bi
=0;}
51 if(bi
>=nx
) {bi
=nx
-1;if(ai
>=nx
) ai
=nx
-1;}
54 if(aj
<0) {aj
=0;if(bj
<0) bj
=0;}
55 if(bj
>=ny
) {bj
=ny
-1;if(aj
>=ny
) aj
=ny
-1;}
58 di
=i
=step_mod(ci
,nx
);apx
=px
=step_div(ci
,nx
)*sx
;
59 dj
=j
=step_mod(cj
,ny
);apy
=py
=step_div(cj
,ny
)*sy
;
60 inc1
=nx
+di
-step_mod(bi
,nx
);
65 /** Starts the loop by finding the first particle within the container to
67 * \return True if there is any particle to consider, false otherwise. */
68 bool c_loop_subset_2d::start() {
69 while(co
[ij
]==0) {if(!next_block()) return false;}
70 while(mode
!=no_check
&&out_of_bounds()) {
72 while(q
>=co
[ij
]) {q
=0;if(!next_block()) return false;}
77 /** Initializes the class to loop over all particles in a rectangular box.
78 * \param[in] (xmin,xmax) the minimum and maximum x coordinates of the box.
79 * \param[in] (ymin,ymax) the minimum and maximum y coordinates of the box.
80 * \param[in] bounds_test whether to do detailed bounds checking. If this is
81 * false then the class will loop over all particles in
82 * blocks that overlap the given box. If it is true, the
83 * particle will only loop over the particles which
84 * actually lie within the box.
85 * \return True if there is any valid point to loop over, false otherwise. */
86 void c_loop_subset_2d::setup_box(double xmin
,double xmax
,double ymin
,double ymax
,bool bounds_test
) {
87 if(bounds_test
) {mode
=rectangle
;v0
=xmin
;v1
=xmax
;v2
=ymin
;v3
=ymax
;} else mode
=no_check
;
88 ai
=step_int((xmin
-ax
)*xsp
);
89 bi
=step_int((xmax
-ax
)*xsp
);
90 aj
=step_int((ymin
-ay
)*ysp
);
91 bj
=step_int((ymax
-ay
)*ysp
);
95 /** Computes whether the current point is out of bounds, relative to the
97 * \return True if the point is out of bounds, false otherwise. */
98 bool c_loop_subset_2d::out_of_bounds() {
99 double *pp(p
[ij
]+ps
*q
);
101 double fx(*pp
+px
-v0
),fy(pp
[1]+py
-v1
);
102 return fx
*fx
+fy
*fy
>v2
;
104 double f(*pp
+px
);if(f
<v0
||f
>v1
) return true;
105 f
=pp
[1]+py
;return f
<v2
||f
>v3
;
109 /** Returns the next block to be tested in a loop, and updates the periodicity
110 * vector if necessary. */
111 bool c_loop_subset_2d::next_block() {
114 if(ci
<nx
-1) {ci
++;ij
++;} else {ci
=0;ij
+=1-nx
;px
+=sx
;}
117 i
=ai
;ci
=di
;px
=apx
;j
++;
118 if(cj
<ny
-1) {cj
++;ij
+=inc1
;} else {cj
=0;ij
+=inc1
-nxy
;py
+=sy
;}
123 /** Extends the memory available for storing the ordering. */
124 void particle_order::add_ordering_memory() {
125 int *no
=new int[size
<<2],*nop
=no
,*opp
=o
;
126 while(opp
<op
) *(nop
++)=*(opp
++);
128 size
<<=1;o
=no
;op
=nop
;