OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
vector_dist_MP_unit_tests.cpp
1 /*
2  * vector_dist_MP_unit_tests.hpp
3  *
4  * Created on: Oct 14, 2016
5  * Author: i-bird
6  */
7 
8 #define BOOST_TEST_DYN_LINK
9 #include <boost/test/unit_test.hpp>
10 
11 #include "Vector/vector_dist_multiphase_functions.hpp"
12 #include "VCluster/VCluster.hpp"
13 #include "Vector/vector_dist.hpp"
14 
15 BOOST_AUTO_TEST_SUITE( vector_dist_multiphase_test )
16 
17 BOOST_AUTO_TEST_CASE( vector_dist_multiphase_cell_list_test )
18 {
19  if (create_vcluster().getProcessingUnits() > 24)
20  return;
21 
22  size_t sz[3] = {60,60,40};
23 
24  // The domain
25  Box<3,float> box({-1000.0,-1000.0,-1000.0},{2000.0,2000.0,1000.0});
26 
27  // Boundary conditions
28  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
29 
30  int rank_test = create_vcluster().rank();
31  float r_cut = 51.0;
32 
33  // ghost, big enough to contain the interaction radius
34  Ghost<3,float> ghost(r_cut);
35 
37 
38  // first phase
39  phases.add( vector_dist<3,float, aggregate<double,double>>(0,box,bc,ghost) );
40 
41  // The other 3 phases
42  phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) );
43  phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) );
44  phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) );
45 
46  // Fill the phases with particles
47 
48  auto g_it = phases.get(0).getGridIterator(sz);
49 
50  while (g_it.isNext())
51  {
52  auto key = g_it.get();
53 
54  // Add a particle to all the phases
55  phases.get(0).add();
56  phases.get(1).add();
57  phases.get(2).add();
58  phases.get(3).add();
59 
60  phases.get(0).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
61  phases.get(0).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
62  phases.get(0).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
63 
64  phases.get(1).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
65  phases.get(1).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
66  phases.get(1).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
67 
68  phases.get(2).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
69  phases.get(2).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
70  phases.get(2).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
71 
72  phases.get(3).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
73  phases.get(3).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
74  phases.get(3).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
75 
76  ++g_it;
77  }
78 
79  // Sync all phases
80  for (size_t i = 0 ; i < 4 ; i++)
81  {
82  phases.get(i).map();
83  }
84 
85  // randomize a little the particles
86 
87  for (size_t p = 0 ; p < phases.size() ; p++)
88  {
90 
91  for (size_t j = 0 ; j < phases.get(p).size_local() ; j++)
92  {
93  vt.add(phases.get(p).getPos((j + p*133) % phases.get(p).size_local()));
94  }
95  phases.get(p).getPosVector().swap(vt);
96  }
97 
98  // Sync all phases
99  for (size_t i = 0 ; i < 4 ; i++)
100  {
101  phases.get(i).ghost_get<>();
102  }
103 
104  // Get the cell list of the phase 0 and 1
105  auto CL_phase0 = phases.get(0).getCellList(r_cut);
106  auto CL_phase1 = phases.get(1).getCellList(r_cut);
107 
108  // This function create a Verlet-list between phases 0 and 1
109  auto NN_ver01 = createVerlet(phases.get(0),phases.get(1),CL_phase1,r_cut);
110 
111  // Check NNver0_1
112 
113  bool ret = true;
114  auto it = phases.get(0).getDomainIterator();
115 
116  while (it.isNext())
117  {
118  auto p = it.get();
119  auto Np = NN_ver01.getNNIterator<NO_CHECK>(p.getKey());
120 
121  size_t nn_count = 0;
122 
123  // For each neighborhood of the particle p
124  while (Np.isNext())
125  {
126  // Count the number of particles
127  nn_count++;
128 
129  ++Np;
130  }
131 
132  ret &= nn_count == 7ul;
133 
134  ++it;
135  }
136 
137  BOOST_REQUIRE_EQUAL(ret,true);
138 
139  // Sync all phases
140  for (size_t i = 0 ; i < 4 ; i++)
141  {
142  phases.get(i).map();
143  phases.get(i).ghost_get<>();
144  }
145 
146  // NN_ver0_all
147 
148  // This function create an "Empty" Multiphase Cell List
149  auto CL_all = createCellListM<2>(phases,r_cut);
150 
151  // This create a Verlet-list between phase 0 and all the other phases
152  auto NNver0_all = createVerletM<2>(0,phases.get(0),phases,CL_all,r_cut);
153 
154  it = phases.get(0).getDomainIterator();
155 
156  while (it.isNext())
157  {
158  auto p = it.get();
159  auto Np = NNver0_all.getNNIterator<NO_CHECK>(p.getKey());
160 
161  size_t nn_cout[4] = {0,0,0,0};
162 
163  // For each neighborhood of the particle p
164  while (Np.isNext())
165  {
166  // Get from which phase it come from
167  auto ph_q = Np.getV();
168 
169  nn_cout[ph_q]++;
170 
171  ++Np;
172  }
173 
174  ret &= nn_cout[0] == 7;
175  ret &= nn_cout[1] == 7;
176  ret &= nn_cout[2] == 7;
177  ret &= nn_cout[3] == 7;
178 
179  ++it;
180  }
181 
182  BOOST_REQUIRE_EQUAL(ret,true);
183 }
184 
185 
186 BOOST_AUTO_TEST_CASE( vector_dist_multiphase_cell_list_sym_test )
187 {
188  if (create_vcluster().getProcessingUnits() > 24)
189  return;
190 
191  size_t sz[3] = {60,60,40};
192 
193  // The domain
194  Box<3,float> box({-1000.0,-1000.0,-1000.0},{2000.0,2000.0,1000.0});
195 
196  // Boundary conditions
197  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
198 
199  float r_cut = 51.0;
200 
201  // ghost, big enough to contain the interaction radius
202  Ghost<3,float> ghost(r_cut);
203 
205 
206  // first phase
207  phases.add( vector_dist<3,float, aggregate<size_t>>(0,box,bc,ghost) );
208 
209  // The other 3 phases
210  phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) );
211  phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) );
212  phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) );
213 
214  // Fill the phases with particles
215 
216  auto g_it = phases.get(0).getGridIterator(sz);
217 
218  while (g_it.isNext())
219  {
220  auto key = g_it.get();
221 
222  // Add a particle to all the phases
223  phases.get(0).add();
224  phases.get(1).add();
225  phases.get(2).add();
226  phases.get(3).add();
227 
228  phases.get(0).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
229  phases.get(0).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
230  phases.get(0).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
231 
232  phases.get(1).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
233  phases.get(1).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
234  phases.get(1).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
235 
236  phases.get(2).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
237  phases.get(2).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
238  phases.get(2).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
239 
240  phases.get(3).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0);
241  phases.get(3).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1);
242  phases.get(3).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2);
243 
244  ++g_it;
245  }
246 
247  // Sync all phases
248  for (size_t i = 0 ; i < 4 ; i++)
249  {
250  phases.get(i).map();
251  }
252 
253  // randomize a little the particles
254 
255  for (size_t p = 0 ; p < phases.size() ; p++)
256  {
258 
259  for (size_t j = 0 ; j < phases.get(p).size_local() ; j++)
260  {
261  vt.add(phases.get(p).getPos((j + p*133) % phases.get(p).size_local()));
262  }
263  phases.get(p).getPosVector().swap(vt);
264  }
265 
266  // Sync all phases
267  for (size_t i = 0 ; i < 4 ; i++)
268  {
269  phases.get(i).ghost_get<>();
270  }
271 
272  // Get the cell list of the phase 0 and 1
273  auto CL_phase0 = phases.get(0).getCellListSym(r_cut);
274  auto CL_phase1 = phases.get(1).getCellListSym(r_cut);
275 
276  // This function create a Verlet-list between phases 0 and 1
277  auto NN_ver01 = createVerletSym(phases.get(0),phases.get(1),CL_phase1,r_cut);
278 
279  // Check NNver0_1
280 
281  bool ret = true;
282  auto it = phases.get(0).getDomainIterator();
283 
284  while (it.isNext())
285  {
286  auto p = it.get();
287  auto Np = NN_ver01.getNNIterator<NO_CHECK>(p.getKey());
288 
289  // For each neighborhood of the particle p
290  while (Np.isNext())
291  {
292  // Neighborhood particle q
293  auto q = Np.get();
294 
295  phases.get(0).getPropWrite<0>(p)++;
296  phases.get(1).getPropWrite<0>(q)++;
297 
298  ++Np;
299  }
300 
301  ++it;
302  }
303 
304  phases.get(0).ghost_put<add_,0>();
305  phases.get(1).ghost_put<add_,0>();
306 
307 #ifdef SE_CLASS3
308 
309  phases.get(1).getDomainIterator();
310 
311 #endif
312 
313  it = phases.get(0).getDomainIterator();
314  while (it.isNext())
315  {
316  auto p = it.get();
317 
318  ret &= phases.get(0).getPropRead<0>(p) == 7;
319  ret &= phases.get(1).getPropRead<0>(p) == 7;
320 
321  ++it;
322  }
323 
324  BOOST_REQUIRE_EQUAL(ret,true);
325 
326  // Sync all phases
327  for (size_t i = 0 ; i < 4 ; i++)
328  {
329  phases.get(i).map();
330  phases.get(i).ghost_get<>();
331  }
332 
333  // Reset counter on all phases
334 
335  for (size_t i = 0 ; i < phases.size() ; i++)
336  {
337  it = phases.get(i).getDomainAndGhostIterator();
338  while (it.isNext())
339  {
340  auto p = it.get();
341 
342  phases.get(i).getPropWrite<0>(p) = 0;
343 
344  ++it;
345  }
346  }
347 
348  // NN_ver0_all
349 
350  // This function create an "Empty" Multiphase Cell List
351  auto CL_all = createCellListSymM<2>(phases,r_cut);
352 
353  typedef decltype(createVerletSymM<2>(0,phases.get(0),phases,CL_all,r_cut)) verlet_type;
354 
355  verlet_type NNver_all[4];
356 
357  // This create a Verlet-list between each phase to all the other phases
358  NNver_all[0] = createVerletSymM<2>(0,phases.get(0),phases,CL_all,r_cut);
359  NNver_all[1] = createVerletSymM<2>(1,phases.get(1),phases,CL_all,r_cut);
360  NNver_all[2] = createVerletSymM<2>(2,phases.get(2),phases,CL_all,r_cut);
361  NNver_all[3] = createVerletSymM<2>(3,phases.get(3),phases,CL_all,r_cut);
362 
363  // all phases to all phases
364 
365  for (size_t i = 0 ; i < phases.size() ; i++)
366  {
367  it = phases.get(i).getDomainIterator();
368 
369  while (it.isNext())
370  {
371  auto p = it.get();
372  auto Np = NNver_all[i].getNNIterator<NO_CHECK>(p.getKey());
373 
374  // For each neighborhood of the particle p
375  while (Np.isNext())
376  {
377  // Get the particle q near to p
378  auto q = Np.getP();
379 
380  // Get from which phase it come from
381  auto ph_q = Np.getV();
382 
383  phases.get(i).getPropWrite<0>(p)++;
384  phases.get(ph_q).getPropWrite<0>(q)++;
385 
386  ++Np;
387  }
388 
389  ++it;
390  }
391  }
392 
393  phases.get(0).ghost_put<add_,0>();
394  phases.get(1).ghost_put<add_,0>();
395  phases.get(2).ghost_put<add_,0>();
396  phases.get(3).ghost_put<add_,0>();
397 
398 #ifdef SE_CLASS3
399 
400  it = phases.get(1).getDomainIterator();
401  it = phases.get(2).getDomainIterator();
402  it = phases.get(3).getDomainIterator();
403 
404 #endif
405 
406  it = phases.get(0).getDomainIterator();
407  while (it.isNext())
408  {
409  auto p = it.get();
410 
411  ret &= phases.get(0).getPropRead<0>(p) == 32;
412  ret &= phases.get(1).getPropRead<0>(p) == 32;
413  ret &= phases.get(2).getPropRead<0>(p) == 32;
414  ret &= phases.get(3).getPropRead<0>(p) == 32;
415 
416  if (ret == false)
417  {
418  std::cout << phases.get(0).getPropRead<0>(p) << std::endl;
419  std::cout << phases.get(1).getPropRead<0>(p) << std::endl;
420  std::cout << phases.get(2).getPropRead<0>(p) << std::endl;
421  std::cout << phases.get(3).getPropRead<0>(p) << std::endl;
422  }
423 
424  ++it;
425  }
426 
427  BOOST_REQUIRE_EQUAL(ret,true);
428 }
429 
430 BOOST_AUTO_TEST_SUITE_END()
431 
This structure define the operation add to use with copy general.
size_t size()
Stub size.
Definition: map_vector.hpp:211
Definition: Ghost.hpp:39
Distributed vector.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:214
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202