OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
CellList_test.hpp
1 /*
2  * CellList_test.hpp
3  *
4  * Created on: Mar 23, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #include "CellList.hpp"
9 #include "CellListM.hpp"
10 #include "Grid/grid_sm.hpp"
11 
12 #ifndef CELLLIST_TEST_HPP_
13 #define CELLLIST_TEST_HPP_
14 
15 
21 template<unsigned int dim, typename T, typename CellS> void Test_cell_s(SpaceBox<dim,T> & box)
22 {
24  //Space where is living the Cell list
25  //SpaceBox<dim,T> box({0.0f,0.0f,0.0f},{1.0f,1.0f,1.0f});
26 
27  // Subdivisions
28  size_t div[dim] = {16,16,16};
29 
30  // Origin
31  Point<dim,T> org({0.0,0.0,0.0});
32 
33  // id Cell list
34  CellS cl2(box,div);
36 
37  // grid info
38  grid_sm<dim,void> g_info(div);
39 
40  // Test force reallocation in case of Cell list fast
41  for (size_t i = 0 ; i < CELL_REALLOC * 3 ; i++)
42  {
43  cl2.add(org,i);
44  }
45 
46  // Check the elements
47  BOOST_REQUIRE_EQUAL(cl2.getNelements(cl2.getCell(org)),CELL_REALLOC * 3ul);
48  for (size_t i = 0 ; i < CELL_REALLOC * 3 ; i++)
49  {
50  BOOST_REQUIRE_EQUAL(cl2.get(cl2.getCell(org),i),i);
51  }
52 
54 
55  // id Cell list
56  CellS cl1(box,div);
57 
58  // Create a grid iterator
59  grid_key_dx_iterator<dim> g_it(g_info);
60 
61  // Iterate through each element
62  // Add 1 element for each cell
63 
64  // Usefull definition of points
65  Point<dim,T> end = box.getP2() - box.getP1();
66  Point<dim,T> middle = end / div / 2.0;
67  Point<dim,T> spacing = end / div;
68 
69  Point<dim,T> offset[dim] = {middle,middle,middle};
70 
71  // Create offset shift vectors
72  for (size_t i = 0 ; i < dim ; i++)
73  {
74  offset[i].get(i) += (1.0 / div[i]) / 8.0;
75  }
76 
78  size_t id = 0;
79 
80  while (g_it.isNext())
81  {
82  // Add 2 particles on each cell
83 
84  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
85  key = pmul(key,spacing) + offset[0] + box.getP1();
86  pos.add(key);
87 
88  cl1.add(key,id);
89  ++id;
90 
91  key = Point<dim,T>(g_it.get().toPoint());
92  key = pmul(key,spacing) + offset[1] + box.getP1();
93  pos.add(key);
94 
95  cl1.add(key,id);
96  ++id;
97 
98  ++g_it;
99  }
100 
102 
103  // check the cell are correctly filled
104 
105  // reset iterator
106  g_it.reset();
107 
108  while (g_it.isNext())
109  {
110  // Check that there are 2 particles on each cell
111 
112  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
113  key = pmul(key,spacing) + offset[2] + box.getP1();
114 
115  size_t cell = cl1.getCell(key);
116  size_t n_ele = cl1.getNelements(cell);
117 
118  BOOST_REQUIRE_EQUAL(n_ele,2ul);
119  BOOST_REQUIRE_EQUAL((long int)(cl1.get(cell,1) - cl1.get(cell,0)),1);
120 
121  ++g_it;
122  }
123 
124  // reset itarator
125  g_it.reset();
126 
128 
129  while (g_it.isNext())
130  {
131  // remove 1 particle on each cell
132 
133  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
134  key = pmul(key,spacing) + offset[0] + box.getP1();
135 
136  auto cell = cl1.getCell(key);
137 
138  // Remove the first particle in the cell
139  cl1.remove(cell,0);
140  ++g_it;
141  }
142 
144 
145  // Check we have 1 object per cell
146  g_it.reset();
147 
148  while (g_it.isNext())
149  {
150  // remove 1 particle on each cell
151 
152  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
153  key = pmul(key,spacing) + offset[0] + box.getP1();
154 
155  auto cell = cl1.getCell(key);
156  size_t n_ele = cl1.getNelements(cell);
157 
158  BOOST_REQUIRE_EQUAL(n_ele,1ul);
159  ++g_it;
160  }
161 
162 
163  // Check we have 1 object per cell
164 
165  // Create a grid iterator
166  grid_key_dx<dim> p1(1,1,1);
167  grid_key_dx<dim> p2(div[0]-2,div[1]-2,div[2]-2);
168  grid_key_dx_iterator_sub<dim> g_it_s(g_info,p1,p2);
169  id = 0;
170 
171  while (g_it_s.isNext())
172  {
174 
175  Point<dim,T> key = Point<dim,T>(g_it_s.get().toPoint());
176  key = pmul(key,spacing) + offset[0] + box.getP1();
177 
178  auto NN = cl1.template getNNIterator<NO_CHECK>(cl1.getCell(key));
179  size_t total = 0;
180 
181  while(NN.isNext())
182  {
183  // total
184 
185  total++;
186 
187  ++NN;
188  }
189 
191 
192  BOOST_REQUIRE_EQUAL(total,(size_t)openfpm::math::pow(3,dim));
193 
194  // in SE1_CLASS the cell list consider this construction as an hack
195  // disable the test
196 
197 #ifndef SE_CLASS1
198 
199  id = cl1.get(cl1.getCell(key),0);
200  auto NNSym = cl1.template getNNIteratorSym<NO_CHECK>(cl1.getCell(key),id,pos);
201  total = 0;
202 
203  while(NNSym.isNext())
204  {
205  // total
206 
207  total++;
208 
209  ++NNSym;
210  }
211 
212  BOOST_REQUIRE_EQUAL(total,(size_t)openfpm::math::pow(3,dim) / 2 + 1);
213 
214 #endif
215 
216  ++g_it_s;
217  }
218 
219 }
220 
221 
227 template<unsigned int dim, typename T, typename CellS> void Test_cell_sM(SpaceBox<dim,T> & box)
228 {
229  //Space where is living the Cell list
230  //SpaceBox<dim,T> box({0.0f,0.0f,0.0f},{1.0f,1.0f,1.0f});
231 
232  // Subdivisions
233  size_t div[dim] = {16,16,16};
234 
235  // Origin
236  Point<dim,T> org({0.0,0.0,0.0});
237 
238  // grid info
239  grid_sm<dim,void> g_info(div);
240 
242 
243  // CellS = CellListM<dim,T,8>
244  CellS cl1(box,div);
245 
246  // Create a grid iterator
247  grid_key_dx_iterator<dim> g_it(g_info);
248 
249  // Iterate through each element
250  // Add 1 element for each cell
251 
252  // Usefull definition of points
253  Point<dim,T> end = box.getP2() - box.getP1();
254  Point<dim,T> middle = end / div / 2.0;
255  Point<dim,T> spacing = end / div;
256 
257  Point<dim,T> offset[dim] = {middle,middle,middle};
258 
259  // Create offset shift vectors
260  for (size_t i = 0 ; i < dim ; i++)
261  {
262  offset[i].get(i) += (1.0 / div[i]) / 8.0;
263  }
264 
267 
269  phases.add(pos_v<dim,T>(phase1));
270  phases.add(pos_v<dim,T>(phase2));
271 
272  size_t id = 0;
273 
274  while (g_it.isNext())
275  {
276  // Add 2 particles on each cell
277 
278  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
279  key = pmul(key,spacing) + offset[0] + box.getP1();
280 
281  phase1.add(key);
282 
283  cl1.add(key,id,0);
284 
285  key = Point<dim,T>(g_it.get().toPoint());
286  key = pmul(key,spacing) + offset[1] + box.getP1();
287 
288  phase2.add(key);
289  cl1.add(key,id,1);
290  ++id;
291 
292  ++g_it;
293  }
294 
295  // check the cell are correctly filled
296 
297  // reset iterator
298  g_it.reset();
299 
300  while (g_it.isNext())
301  {
302  // Add 2 particles on each cell
303 
304  Point<dim,T> key = Point<dim,T>(g_it.get().toPoint());
305  key = pmul(key,spacing) + offset[2] + box.getP1();
306 
307  size_t cell = cl1.getCell(key);
308  size_t n_ele = cl1.getNelements(cell);
309 
310  size_t p1 = cl1.getP(cell,1);
311  size_t p2 = cl1.getP(cell,0);
312 
313  size_t v1 = cl1.getV(cell,1);
314  size_t v2 = cl1.getV(cell,0);
315 
316  BOOST_REQUIRE_EQUAL(n_ele,2ul);
317  BOOST_REQUIRE_EQUAL((long int)(p1 - p2),0);
318  BOOST_REQUIRE_EQUAL((long int)(v1 - v2),1);
319  ++g_it;
320  }
321 }
322 
323 template<typename CellList> void Test_CellDecomposer_consistent()
324 {
325  Box<2,float> bx({-1.0/3.0,-1.0/3.0},{1.0/3.0,1.0/3.0});
326 
327  size_t div[2] = {36,36};
328 
329  CellDecomposer_sm<2,float,shift<2,float>> cd(bx,div,1);
330 
331  Box<2,float> bx_sub({-1.0/5.0,-1.0/5.0},{1.0/5.0,1.0/5.0});
332 
333  size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
334  CellList cl(cd,bx_sub);
335  Box<2,long int> bx_int = cd.convertDomainSpaceIntoGridUnits(bx_sub,bc);
336 
337  BOOST_REQUIRE_EQUAL(bx_int.getLow(0),8);
338  BOOST_REQUIRE_EQUAL(bx_int.getLow(1),8);
339 
340  BOOST_REQUIRE_EQUAL(bx_int.getHigh(0),28);
341  BOOST_REQUIRE_EQUAL(bx_int.getHigh(1),28);
342 
343  cd.convertCellUnitsIntoDomainSpace(bx_sub);
344 
345  BOOST_REQUIRE_EQUAL(bx_sub.getLow(0),-1.0f/5.0f);
346  BOOST_REQUIRE_EQUAL(bx_sub.getLow(1),-1.0f/5.0f);
347 
348  BOOST_REQUIRE_EQUAL(bx_sub.getHigh(0),1.0f/5.0f);
349  BOOST_REQUIRE_EQUAL(bx_sub.getHigh(1),1.0f/5.0f);
350 }
351 
352 BOOST_AUTO_TEST_SUITE( CellList_test )
353 
354 BOOST_AUTO_TEST_CASE( CellList_use)
355 {
356  std::cout << "Test cell list" << "\n";
357 
358  SpaceBox<3,double> box({0.0f,0.0f,0.0f},{1.0f,1.0f,1.0f});
359  SpaceBox<3,double> box2({-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f});
360  Test_cell_s<3,double,CellList<3,double,Mem_fast<>>>(box);
361  Test_cell_s<3,double,CellList<3,double,Mem_fast<>,shift<3,double>> >(box2);
362  Test_cell_sM<3,double,CellListM<3,double,8>>(box);
363  Test_cell_sM<3,double,CellListM<3,double,8>>(box2);
364 
365 
366  Test_cell_s<3,double,CellList<3,double,Mem_bal<>>>(box);
367  Test_cell_s<3,double,CellList<3,double,Mem_mw<>>>(box);
368 
369  std::cout << "End cell list" << "\n";
370 
371  // Test the cell list
372 }
373 
374 BOOST_AUTO_TEST_CASE( CellList_consistent )
375 {
376  Test_CellDecomposer_consistent<CellList<2,float,Mem_fast<>,shift<2,float>>>();
377 }
378 
379 BOOST_AUTO_TEST_CASE( CellList_NNc_csr_calc )
380 {
382 
383  NNcalc_csr(cNN);
384 
385  BOOST_REQUIRE_EQUAL(cNN.size(),14ul);
386 
387  BOOST_REQUIRE(cNN.get(0).first == grid_key_dx<3>(0,0,0));
388  BOOST_REQUIRE(cNN.get(0).second == grid_key_dx<3>(0,0,0));
389 
390  BOOST_REQUIRE(cNN.get(1).first == grid_key_dx<3>(0,0,0));
391  BOOST_REQUIRE(cNN.get(1).second == grid_key_dx<3>(0,0,1));
392 
393  BOOST_REQUIRE(cNN.get(2).first == grid_key_dx<3>(0,0,1));
394  BOOST_REQUIRE(cNN.get(2).second == grid_key_dx<3>(0,1,0));
395 
396  BOOST_REQUIRE(cNN.get(3).first == grid_key_dx<3>(0,0,0));
397  BOOST_REQUIRE(cNN.get(3).second == grid_key_dx<3>(0,1,0));
398 
399  BOOST_REQUIRE(cNN.get(4).first == grid_key_dx<3>(0,0,0));
400  BOOST_REQUIRE(cNN.get(4).second == grid_key_dx<3>(0,1,1));
401 
402  BOOST_REQUIRE(cNN.get(5).first == grid_key_dx<3>(0,1,1));
403  BOOST_REQUIRE(cNN.get(5).second == grid_key_dx<3>(1,0,0));
404 
405  BOOST_REQUIRE(cNN.get(6).first == grid_key_dx<3>(0,1,0));
406  BOOST_REQUIRE(cNN.get(6).second == grid_key_dx<3>(1,0,0));
407 
408  BOOST_REQUIRE(cNN.get(7).first == grid_key_dx<3>(0,1,0));
409  BOOST_REQUIRE(cNN.get(7).second == grid_key_dx<3>(1,0,1));
410 
411  BOOST_REQUIRE(cNN.get(8).first == grid_key_dx<3>(0,0,1));
412  BOOST_REQUIRE(cNN.get(8).second == grid_key_dx<3>(1,0,0));
413 
414  BOOST_REQUIRE(cNN.get(9).first == grid_key_dx<3>(0,0,0));
415  BOOST_REQUIRE(cNN.get(9).second == grid_key_dx<3>(1,0,0));
416 
417  BOOST_REQUIRE(cNN.get(10).first == grid_key_dx<3>(0,0,0));
418  BOOST_REQUIRE(cNN.get(10).second == grid_key_dx<3>(1,0,1));
419 
420  BOOST_REQUIRE(cNN.get(11).first == grid_key_dx<3>(0,0,1));
421  BOOST_REQUIRE(cNN.get(11).second == grid_key_dx<3>(1,1,0));
422 
423  BOOST_REQUIRE(cNN.get(12).first == grid_key_dx<3>(0,0,0));
424  BOOST_REQUIRE(cNN.get(12).second == grid_key_dx<3>(1,1,0));
425 
426  BOOST_REQUIRE(cNN.get(13).first == grid_key_dx<3>(0,0,0));
427  BOOST_REQUIRE(cNN.get(13).second == grid_key_dx<3>(1,1,1));
428 
429 }
430 
431 BOOST_AUTO_TEST_SUITE_END()
432 
433 #endif /* CELLLIST_TEST_HPP_ */
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
size_t size()
Stub size.
Definition: map_vector.hpp:70
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
Structure that contain a reference to a vector of particles.
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:605
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
This class represent an N-dimensional box.
Definition: Box.hpp:56
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
Class for FAST cell list implementation.
Definition: CellList.hpp:269
Point< dim, T > getP2() const
Get the point p2.
Definition: Box.hpp:619