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