OpenFPM  5.2.0
Project that contain the implementation of distributed structures
interpolation_unit_tests.cpp
1 /*
2  * interpolation_unit_tests.hpp
3  *
4  * Created on: May 5, 2017
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_NUMERICS_SRC_INTERPOLATION_INTERPOLATION_UNIT_TESTS_HPP_
9 #define OPENFPM_NUMERICS_SRC_INTERPOLATION_INTERPOLATION_UNIT_TESTS_HPP_
10 
11 #define BOOST_TEST_DYN_LINK
12 #include <boost/test/unit_test.hpp>
13 
14 #include "interpolation/mp4_kernel.hpp"
15 #include "interpolation/lambda_kernel.hpp"
16 #include "interpolation/z_spline.hpp"
17 #include "interpolation.hpp"
18 #include <boost/math/special_functions/pow.hpp>
19 #include <Vector/vector_dist.hpp>
20 #include <Operators/Vector/vector_dist_operators.hpp>
21 #include <FiniteDifference/FD_op.hpp>
22 #include <Grid/grid_dist_id.hpp>
23 
24 BOOST_AUTO_TEST_SUITE( interpolation_test )
25 
26 template<typename grid, unsigned int mom_p> void momenta_grid(grid & gd,typename grid::stype (& mom_tot)[grid::dims])
27 {
28  auto it = gd.getDomainGhostIterator();
29 
30  for (size_t i = 0 ; i < grid::dims ; i++)
31  mom_tot[i] = 0.0;
32 
33  while (it.isNext())
34  {
35  auto key = it.get();
36  auto key_g = gd.getGKey(key);
37 
38  for (size_t i = 0 ; i < grid::dims ; i++)
39  {
40  typename grid::stype coord = gd.spacing(i)*key_g.get(i);
41 
42  mom_tot[i] += boost::math::pow<mom_p>(coord)*gd.template getProp<0>(key);
43  }
44 
45  ++it;
46  }
47 }
48 
49 template<typename grid, unsigned int mom_p> void momenta_grid_domain(grid & gd,typename grid::stype (& mom_tot)[grid::dims])
50 {
51  auto it = gd.getDomainIterator();
52 
53  for (size_t i = 0 ; i < grid::dims ; i++)
54  mom_tot[i] = 0.0;
55 
56  while (it.isNext())
57  {
58  auto key = it.get();
59  auto key_g = gd.getGKey(key);
60 
61  for (size_t i = 0 ; i < grid::dims ; i++)
62  {
63  typename grid::stype coord = gd.spacing(i)*key_g.get(i);
64 
65  mom_tot[i] += boost::math::pow<mom_p>(coord)*gd.template getProp<0>(key);
66  }
67 
68  ++it;
69  }
70 }
71 
72 template<typename vector, unsigned int mom_p> void momenta_vector(vector & vd,typename vector::stype (& mom_tot)[vector::dims])
73 {
74  auto it = vd.getDomainIterator();
75 
76  for (size_t i = 0 ; i < vector::dims ; i++)
77  mom_tot[i] = 0.0;
78 
79  while (it.isNext())
80  {
81  auto key = it.get();
82 
83  for (size_t i = 0 ; i < vector::dims ; i++)
84  {
85  typename vector::stype coord = vd.getPos(key)[i];
86 
87  mom_tot[i] += boost::math::pow<mom_p>(coord)*vd.template getProp<0>(key);
88  }
89 
90  ++it;
91  }
92 }
93 
94 template<unsigned int dim, typename T,typename Kernel, typename grid, typename vector>
95 void interp_test(grid & gd, vector & vd, bool single_particle,unsigned int numberOfMomenta)
96 {
97  // Reset the grid
98 
99  auto it2 = gd.getDomainGhostIterator();
100 
101  while (it2.isNext())
102  {
103  auto key = it2.get();
104 
105  gd.template get<0>(key) = 0.0;
106 
107  ++it2;
108  }
109 
111 
112  if (single_particle == false)
113  {inte.template p2m<0,0>(vd,gd);}
114  else
115  {
116  auto it = vd.getDomainIterator();
117 
118  while (it.isNext())
119  {
120  auto p = it.get();
121 
122  inte.template p2m<0,0>(vd,gd,p);
123 
124  ++it;
125  }
126  }
127 
128  T mg[dim];
129  T mv[dim];
130  vd.write("Particles");
131  gd.write("Grid");
132 
133  if(numberOfMomenta>=0){
134  momenta_grid<grid,0>(gd,mg);
135  momenta_vector<vector,0>(vd,mv);
136  for (size_t i = 0 ; i < dim ; i++)
137  {BOOST_REQUIRE_CLOSE(mg[i],mv[i],0.001);}
138  }
139 
140  if(numberOfMomenta>=1){
141  momenta_grid<grid,1>(gd,mg);
142  momenta_vector<vector,1>(vd,mv);
143  for (size_t i = 0 ; i < dim ; i++)
144  {BOOST_REQUIRE_CLOSE(mg[i],mv[i],0.001);}
145  }
146 
147  if(numberOfMomenta>=2){
148  momenta_grid<grid,2>(gd,mg);
149  momenta_vector<vector,2>(vd,mv);
150  for (size_t i = 0 ; i < dim ; i++)
151  {BOOST_REQUIRE_CLOSE(mg[i],mv[i],0.001);}
152  }
153 
154  if(numberOfMomenta>=3){
155  momenta_grid<grid,3>(gd,mg);
156  momenta_vector<vector,3>(vd,mv);
157  for (size_t i = 0 ; i < dim ; i++)
158  {BOOST_REQUIRE_CLOSE(mg[i],mv[i],0.001);}
159  }
160 
161  if(numberOfMomenta>=4){
162  momenta_grid<grid,4>(gd,mg);
163  momenta_vector<vector,4>(vd,mv);
164  for (size_t i = 0 ; i < dim ; i++)
165  {BOOST_REQUIRE_CLOSE(mg[i],mv[i],0.001);}
166  }
167 }
168 
169 
170 
171 BOOST_AUTO_TEST_CASE( interpolation_full_single_test_2D )
172 {
173  Box<2,float> domain({0.0,0.0},{1.0,1.0});
174  size_t sz[2] = {64,64};
175 
176  Ghost<2,long int> gg(2);
177  Ghost<2,float> gv(0.01);
178 
179  size_t bc_v[2] = {PERIODIC,PERIODIC};
180 
181  vector_dist<2,float,aggregate<float>> vd(65536,domain,bc_v,gv);
182  grid_dist_id<2,float,aggregate<float>> gd(vd.getDecomposition(),sz,gg);
183 
184  // set one particle on vd
185 
186  auto it = vd.getDomainIterator();
187 
188  while (it.isNext())
189  {
190  auto p = it.get();
191 
192  vd.getPos(p)[0] = (double)rand()/RAND_MAX;
193  vd.getPos(p)[1] = (double)rand()/RAND_MAX;
194 
195  vd.getProp<0>(p) = 5.0;
196 
197  ++it;
198  }
199 
200  vd.map();
201 
202  interp_test<2,float,mp4_kernel<float>>(gd,vd,true,2);
203 }
204  BOOST_AUTO_TEST_CASE( interpolation_full_single_test_2D_double )
205  {
206  Box<2,double> domain({0.0,0.0},{1.0,1.0});
207  size_t sz[2] = {64,64};
208 
209  Ghost<2,long int> gg(3);
210  Ghost<2,double> gv(0.01);
211 
212  size_t bc_v[2] = {PERIODIC,PERIODIC};
213 
214  vector_dist<2,double,aggregate<double>> vd(65536,domain,bc_v,gv);
215  grid_dist_id<2,double,aggregate<double>> gd(vd.getDecomposition(),sz,gg);
216 
217  // set one particle on vd
218 
219  auto it = vd.getDomainIterator();
220 
221  while (it.isNext())
222  {
223  auto p = it.get();
224 
225  vd.getPos(p)[0] = (double)rand()/RAND_MAX;
226  vd.getPos(p)[1] = (double)rand()/RAND_MAX;
227 
228  vd.getProp<0>(p) = 5.0;
229 
230  ++it;
231  }
232 
233  vd.map();
234 
235  interp_test<2,double,lambda4_4kernel<double>>(gd,vd,true,2);
236  }
237 
238 
239 BOOST_AUTO_TEST_CASE( interpolation_full_test_2D )
240 {
241  Box<2,float> domain({0.0,0.0},{1.0,1.0});
242  size_t sz[2] = {64,64};
243 
244  Ghost<2,long int> gg(3);
245  Ghost<2,float> gv(0.01);
246 
247  size_t bc_v[2] = {PERIODIC,PERIODIC};
248 
249  {
250  vector_dist<2,float,aggregate<float>> vd(4096,domain,bc_v,gv);
251  grid_dist_id<2,float,aggregate<float>> gd(vd.getDecomposition(),sz,gg);
252 
253  // set one particle on vd
254 
255  auto it = vd.getDomainIterator();
256 
257  while (it.isNext())
258  {
259  auto p = it.get();
260 
261  vd.getPos(p)[0] = (double)rand()/RAND_MAX;
262  vd.getPos(p)[1] = (double)rand()/RAND_MAX;
263 
264  vd.getProp<0>(p) = 5.0;
265 
266  ++it;
267  }
268 
269  vd.map();
270 
271  // Reset the grid
272  interp_test<2,float,mp4_kernel<float>>(gd,vd,false,2);
273 
274  float mg[2];
275  float mv[2];
276 
277  auto & v_cl = create_vcluster();
278 
279  interpolate<decltype(vd),decltype(gd),mp4_kernel<float>> inte(vd,gd);
280 
281  // We have to do a ghost get before interpolating m2p
282  // Before doing mesh to particle particle must be arranged
283  // into a grid like
284 
285  vd.clear();
286 
287  auto it4 = vd.getGridIterator(sz);
288 
289  while(it4.isNext())
290  {
291  auto key = it4.get();
292 
293  vd.add();
294 
295  vd.getLastPos()[0] = key.get(0) * it4.getSpacing(0) + domain.getLow(0) + 0.1*it4.getSpacing(0);
296  vd.getLastPos()[1] = key.get(1) * it4.getSpacing(1) + domain.getLow(1) + 0.1*it4.getSpacing(1);
297 
298  vd.getLastProp<0>() = 0.0;
299 
300  ++it4;
301  }
302 
303  // Reset also the grid
304 
305  auto it5 = gd.getDomainGhostIterator();
306 
307  while(it5.isNext())
308  {
309  auto key = it5.get();
310 
311  gd.get<0>(key) = 0.0;
312 
313  ++it5;
314  }
315  gd.ghost_get<0>();
316 
317  grid_key_dx<2> start({3,3});
318  grid_key_dx<2> stop({(long int)gd.size(0) - 4,(long int)gd.size(1) - 4});
319 
320  auto it6 = gd.getSubDomainIterator(start,stop);
321  while(it6.isNext())
322  {
323  auto key = it6.get();
324 
325  gd.get<0>(key) = 5.0/*(double)rand()/RAND_MAX;*/;
326 
327  ++it6;
328  }
329  gd.ghost_get<0>();
330 
331  vd.map();
332  gd.ghost_get<0>();
333  inte.m2p<0,0>(gd,vd);
334 
335  momenta_grid_domain<decltype(gd),0>(gd,mg);
336  momenta_vector<decltype(vd),0>(vd,mv);
337 
338  v_cl.sum(mg[0]);
339  v_cl.sum(mg[1]);
340  v_cl.sum(mv[0]);
341  v_cl.sum(mv[1]);
342  v_cl.execute();
343 
344  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
345  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
346 
347  momenta_grid_domain<decltype(gd),1>(gd,mg);
348  momenta_vector<decltype(vd),1>(vd,mv);
349 
350  v_cl.sum(mg[0]);
351  v_cl.sum(mg[1]);
352  v_cl.sum(mv[0]);
353  v_cl.sum(mv[1]);
354  v_cl.execute();
355 
356  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
357  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
358 
359  momenta_grid_domain<decltype(gd),2>(gd,mg);
360  momenta_vector<decltype(vd),2>(vd,mv);
361 
362  v_cl.sum(mg[0]);
363  v_cl.sum(mg[1]);
364  v_cl.sum(mv[0]);
365  v_cl.sum(mv[1]);
366  v_cl.execute();
367 
368  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
369  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
370 
371  }
372 }
373 
374 BOOST_AUTO_TEST_CASE( interpolation_full_single_test_3D )
375 {
376  Box<3,double> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
377  size_t sz[3] = {64,64,64};
378 
379  Ghost<3,long int> gg(2);
380  Ghost<3,double> gv(0.01);
381 
382  size_t bc_v[3] = {PERIODIC,PERIODIC,PERIODIC};
383 
384  vector_dist<3,double,aggregate<double>> vd(65536,domain,bc_v,gv);
385  grid_dist_id<3,double,aggregate<double>> gd(vd.getDecomposition(),sz,gg);
386 
387  // set one particle on vd
388 
389  auto it = vd.getDomainIterator();
390 
391  while (it.isNext())
392  {
393  auto p = it.get();
394 
395  // coverty[dont_call]
396  vd.getPos(p)[0] = (double)rand()/RAND_MAX;
397  // coverty[dont_call]
398  vd.getPos(p)[1] = (double)rand()/RAND_MAX;
399  // coverty[dont_call]
400  vd.getPos(p)[2] = (double)rand()/RAND_MAX;
401 
402  vd.getProp<0>(p) = 5.0;
403 
404  ++it;
405  }
406 
407  vd.map();
408 
409  // Reset the grid
410  interp_test<3,double,mp4_kernel<float>>(gd,vd,true,2);
411 }
412 
413 BOOST_AUTO_TEST_CASE( interpolation_getSubCheck )
414 {
415  Box<3,double> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
416  size_t sz[3] = {64,64,64};
417 
418  Ghost<3,long int> gg(2);
419  Ghost<3,double> gv(0.01);
420 
421  size_t bc_v[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
422 
425 
426  vector vd(0,domain,bc_v,gv);
427  grid_dist_id<3,double,aggregate<double>> gd(vd.getDecomposition(),sz,gg);
428 
429  // interpolate
431 
432  // decomposition
433  auto & dec = vd.getDecomposition();
434 
435  int nl = dec.getNLocalSub();
436 
437  for (int i = 0 ; i < nl ; i++)
438  {
439  int nll = dec.getLocalNIGhost(i);
440  for (int j = 0 ; j < nll ; j++)
441  {
442  auto ibx = dec.getLocalIGhostBox(i,j);
443  int x = dec.getLocalIGhostSub(i,j);
444  auto bx = dec.getSubDomain(x);
445 
446  Point<3,double> p;
447  for (int s = 0; s < 3 ; s++)
448  {
449  Point<3,double> p;
450  for (int s1 = 0; s1 < 3 ; s1++)
451  {
452  p.get(s1) = (ibx.getHigh(s1) - ibx.getLow(s1)) / 2.0 + ibx.getLow(s1);
453  }
454 
455  if (ibx.getLow(s) == bx.getHigh(s))
456  {
457  p.get(s) = ibx.getLow(s);
458  int sub = inte.getSub(p);
459  BOOST_REQUIRE_EQUAL(sub,i);
460  }
461  else if (ibx.getHigh(s) == bx.getLow(s))
462  {
463  p.get(s) = ibx.getHigh(s);
464  int sub = inte.getSub(p);
465  BOOST_REQUIRE_EQUAL(sub,x);
466  }
467  }
468  }
469  }
470 }
471 
472 BOOST_AUTO_TEST_CASE( interpolation_full_test_3D )
473 {
474  Box<3,double> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
475  size_t sz[3] = {64,64,64};
476 
477  Ghost<3,long int> gg(2);
478  Ghost<3,double> gv(0.01);
479 
480  size_t bc_v[3] = {PERIODIC,PERIODIC,PERIODIC};
481 
482  {
483  vector_dist<3,double,aggregate<double>> vd(65536,domain,bc_v,gv);
484  grid_dist_id<3,double,aggregate<double>> gd(vd.getDecomposition(),sz,gg);
485 
486  // set one particle on vd
487 
488  auto it = vd.getDomainIterator();
489 
490  while (it.isNext())
491  {
492  auto p = it.get();
493 
494  vd.getPos(p)[0] = (double)rand()/RAND_MAX;
495  vd.getPos(p)[1] = (double)rand()/RAND_MAX;
496  vd.getPos(p)[2] = (double)rand()/RAND_MAX;
497 
498  vd.getProp<0>(p) = 5.0;
499 
500  ++it;
501  }
502 
503  vd.map();
504 
505  // Reset the grid
506 
507  // Reset the grid
508  interp_test<3,double,mp4_kernel<float>>(gd,vd,false,2);
509 
510  auto & v_cl = create_vcluster();
511  double mg[3];
512  double mv[3];
513  interpolate<decltype(vd),decltype(gd),mp4_kernel<double>> inte(vd,gd);
514 
515  // We have to do a ghost get before interpolating m2p
516  // Before doing mesh to particle particle must be arranged
517  // into a grid like
518 
519  vd.clear();
520 
521  auto it4 = vd.getGridIterator(sz);
522 
523  while(it4.isNext())
524  {
525  auto key = it4.get();
526 
527  vd.add();
528 
529  vd.getLastPos()[0] = key.get(0) * it4.getSpacing(0) + domain.getLow(0) + 0.1*it4.getSpacing(0);
530  vd.getLastPos()[1] = key.get(1) * it4.getSpacing(1) + domain.getLow(1) + 0.1*it4.getSpacing(1);
531  vd.getLastPos()[2] = key.get(2) * it4.getSpacing(2) + domain.getLow(2) + 0.1*it4.getSpacing(2);
532 
533  vd.getLastProp<0>() = 0.0;
534 
535  ++it4;
536  }
537 
538  // Reset also the grid
539 
540  auto it5 = gd.getDomainGhostIterator();
541 
542  while(it5.isNext())
543  {
544  auto key = it5.get();
545 
546  gd.get<0>(key) = 0.0;
547 
548  ++it5;
549  }
550  gd.ghost_get<0>();
551 
552  grid_key_dx<3> start({3,3,3});
553  grid_key_dx<3> stop({(long int)gd.size(0) - 4,(long int)gd.size(1) - 4,(long int)gd.size(2) - 4});
554 
555  auto it6 = gd.getSubDomainIterator(start,stop);
556  while(it6.isNext())
557  {
558  auto key = it6.get();
559 
560  gd.get<0>(key) = 5.0;
561 
562  ++it6;
563  }
564  gd.ghost_get<0>();
565 
566  vd.map();
567  gd.ghost_get<0>();
568  inte.m2p<0,0>(gd,vd);
569 
570  momenta_grid_domain<decltype(gd),0>(gd,mg);
571  momenta_vector<decltype(vd),0>(vd,mv);
572 
573  v_cl.sum(mg[0]);
574  v_cl.sum(mg[1]);
575  v_cl.sum(mg[2]);
576  v_cl.sum(mv[0]);
577  v_cl.sum(mv[1]);
578  v_cl.sum(mv[2]);
579  v_cl.execute();
580 
581  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
582  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
583  BOOST_REQUIRE_CLOSE(mg[2],mv[2],0.001);
584 
585  momenta_grid_domain<decltype(gd),1>(gd,mg);
586  momenta_vector<decltype(vd),1>(vd,mv);
587 
588  v_cl.sum(mg[0]);
589  v_cl.sum(mg[1]);
590  v_cl.sum(mg[2]);
591  v_cl.sum(mv[0]);
592  v_cl.sum(mv[1]);
593  v_cl.sum(mv[2]);
594  v_cl.execute();
595 
596  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
597  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
598  BOOST_REQUIRE_CLOSE(mg[2],mv[2],0.001);
599 
600  momenta_grid_domain<decltype(gd),2>(gd,mg);
601  momenta_vector<decltype(vd),2>(vd,mv);
602 
603  v_cl.sum(mg[0]);
604  v_cl.sum(mg[1]);
605  v_cl.sum(mg[2]);
606  v_cl.sum(mv[0]);
607  v_cl.sum(mv[1]);
608  v_cl.sum(mv[2]);
609  v_cl.execute();
610 
611  BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
612  BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
613  BOOST_REQUIRE_CLOSE(mg[2],mv[2],0.001);
614 
615  }
616 }
617 
618 BOOST_AUTO_TEST_CASE( int_kernel_test )
619 {
620  mp4_kernel<float> mp4;
621 
622  float tot = 0.0;
623 
624  // Check momenta 0
625 
626  tot += mp4.value(-1.3f,0);
627  tot += mp4.value(-0.3f,1);
628  tot += mp4.value(0.7f,2);
629  tot += mp4.value(1.7f,3);
630 
631  BOOST_REQUIRE_CLOSE(tot,1.0f,0.001);
632 
633  // Check momenta 1
634 
635  tot = 0.0;
636 
637  tot += -1.3f*mp4.value(-1.3f,0);
638  tot += -0.3f*mp4.value(-0.3f,1);
639  tot += 0.7f*mp4.value(0.7f,2);
640  tot += 1.7f*mp4.value(1.7f,3);
641 
642  BOOST_REQUIRE_SMALL(tot,0.001f);
643 
644  // Check momenta 2
645 
646  tot = 0.0;
647 
648  tot += (1.3f)*(1.3f)*mp4.value(-1.3f,0);
649  tot += (0.3f)*(0.3f)*mp4.value(-0.3f,1);
650  tot += (0.7f)*(0.7f)*mp4.value(0.7f,2);
651  tot += (1.7f)*(1.7f)*mp4.value(1.7f,3);
652 
653  BOOST_REQUIRE_SMALL(tot,0.001f);
654 
655 
657 
658  tot = 0.0;
659 
660  z_kernel<float,1> zk1;
661 
662  tot += zk1.value(-0.3f,0);
663  tot += zk1.value(0.7f,1);
664 
665  BOOST_REQUIRE_CLOSE(tot,1.0f,0.001);
666 
668 
670 
671  z_kernel<float,3> zk3;
672 
673  tot = 0.0;
674 
675  // Check momenta 0
676 
677  tot += zk3.value(-2.3f,0);
678  tot += zk3.value(-1.3f,1);
679  tot += zk3.value(-0.3f,2);
680  tot += zk3.value(0.7f,3);
681  tot += zk3.value(1.7f,4);
682  tot += zk3.value(2.7f,5);
683 
684  BOOST_REQUIRE_CLOSE(tot,1.0f,0.001);
685 
686  // Check momenta 1
687 
688  tot = 0.0;
689 
690  tot += -2.3*zk3.value(-2.3f,0);
691  tot += -1.3*zk3.value(-1.3f,1);
692  tot += -0.3*zk3.value(-0.3f,2);
693  tot += 0.7*zk3.value(0.7f,3);
694  tot += 1.7*zk3.value(1.7f,4);
695  tot += 2.7*zk3.value(2.7f,5);
696 
697  BOOST_REQUIRE_SMALL(tot,0.001f);
698 
699  // Check momenta 2
700 
701  tot = 0.0;
702 
703  tot += 2.3*2.3*zk3.value(-2.3f,0);
704  tot += 1.3*1.3*zk3.value(-1.3f,1);
705  tot += 0.3*0.3*zk3.value(-0.3f,2);
706  tot += 0.7*0.7*zk3.value(0.7f,3);
707  tot += 1.7*1.7*zk3.value(1.7f,4);
708  tot += 2.7*2.7*zk3.value(2.7f,5);
709 
710  BOOST_REQUIRE_SMALL(tot,0.001f);
711 
712  // Check momenta 3
713 
714  tot = 0.0;
715 
716  tot += -2.3*-2.3*-2.3*zk3.value(-2.3f,0);
717  tot += -1.3*-1.3*-1.3*zk3.value(-1.3f,1);
718  tot += -0.3*-0.3*-0.3*zk3.value(-0.3f,2);
719  tot += 0.7*0.7*0.7*zk3.value(0.7f,3);
720  tot += 1.7*1.7*1.7*zk3.value(1.7f,4);
721  tot += 2.7*2.7*2.7*zk3.value(2.7f,5);
722 
723  BOOST_REQUIRE_SMALL(tot,0.001f);
724 
725 
726  // z4
727 
728  z_kernel<float,4> zk4;
729 
730  // Check momenta 0
731 
732  tot = 0.0;
733 
734  tot += zk4.value(-3.3f,0);
735  tot += zk4.value(-2.3f,1);
736  tot += zk4.value(-1.3f,2);
737  tot += zk4.value(-0.3f,3);
738  tot += zk4.value(0.7f,4);
739  tot += zk4.value(1.7f,5);
740  tot += zk4.value(2.7f,6);
741  tot += zk4.value(3.7f,7);
742 
743  BOOST_REQUIRE_CLOSE(tot,1.0f,0.001);
744 
745  // Check momenta 1
746 
747  tot = 0.0;
748 
749  tot += -3.3*zk4.value(-3.3f,0);
750  tot += -2.3*zk4.value(-2.3f,1);
751  tot += -1.3*zk4.value(-1.3f,2);
752  tot += -0.3*zk4.value(-0.3f,3);
753  tot += 0.7*zk4.value(0.7f,4);
754  tot += 1.7*zk4.value(1.7f,5);
755  tot += 2.7*zk4.value(2.7f,6);
756  tot += 3.7*zk4.value(3.7f,7);
757 
758  BOOST_REQUIRE_SMALL(tot,0.001f);
759 
760  // Check momenta 2
761 
762  tot = 0.0;
763 
764  tot += 3.3*3.3*zk4.value(-3.3f,0);
765  tot += 2.3*2.3*zk4.value(-2.3f,1);
766  tot += 1.3*1.3*zk4.value(-1.3f,2);
767  tot += 0.3*0.3*zk4.value(-0.3f,3);
768  tot += 0.7*0.7*zk4.value(0.7f,4);
769  tot += 1.7*1.7*zk4.value(1.7f,5);
770  tot += 2.7*2.7*zk4.value(2.7f,6);
771  tot += 3.7*3.7*zk4.value(3.7f,7);
772 
773  BOOST_REQUIRE_SMALL(tot,0.001f);
774 
775  // Check momenta 3
776 
777  tot = 0.0;
778 
779  tot += -3.3*-3.3*-3.3*zk4.value(-3.3f,0);
780  tot += -2.3*-2.3*-2.3*zk4.value(-2.3f,1);
781  tot += -1.3*-1.3*-1.3*zk4.value(-1.3f,2);
782  tot += -0.3*-0.3*-0.3*zk4.value(-0.3f,3);
783  tot += 0.7*0.7*0.7*zk4.value(0.7f,4);
784  tot += 1.7*1.7*1.7*zk4.value(1.7f,5);
785  tot += 2.7*2.7*2.7*zk4.value(2.7f,6);
786  tot += 3.7*3.7*3.7*zk4.value(3.7f,7);
787 
788  BOOST_REQUIRE_SMALL(tot,0.001f);
789 
790  // Check momenta 4
791 
792  tot = 0.0;
793 
794  tot += -3.3*-3.3*-3.3*-3.3*zk4.value(-3.3f,0);
795  tot += -2.3*-2.3*-2.3*-2.3*zk4.value(-2.3f,1);
796  tot += -1.3*-1.3*-1.3*-1.3*zk4.value(-1.3f,2);
797  tot += -0.3*-0.3*-0.3*-0.3*zk4.value(-0.3f,3);
798  tot += 0.7*0.7*0.7*0.7*zk4.value(0.7f,4);
799  tot += 1.7*1.7*1.7*1.7*zk4.value(1.7f,5);
800  tot += 2.7*2.7*2.7*2.7*zk4.value(2.7f,6);
801  tot += 3.7*3.7*3.7*3.7*zk4.value(3.7f,7);
802 
803  BOOST_REQUIRE_SMALL(tot,0.001f);
804 }
805 
806 BOOST_AUTO_TEST_CASE( int_kernel_test_double)
807 {
808  mp4_kernel<double> mp4;
809 
810  double tot = 0.0;
811 
812  // Check momenta 0
813 
814  tot += mp4.value(-1.3,0);
815  tot += mp4.value(-0.3,1);
816  tot += mp4.value(0.7,2);
817  tot += mp4.value(1.7,3);
818 
819  BOOST_REQUIRE_CLOSE(tot,1.0,0.001);
820 
821  // Check momenta 1
822 
823  tot = 0.0;
824 
825  tot += -1.3*mp4.value(-1.3,0);
826  tot += -0.3*mp4.value(-0.3,1);
827  tot += 0.7*mp4.value(0.7,2);
828  tot += 1.7*mp4.value(1.7,3);
829 
830  BOOST_REQUIRE_SMALL(tot,0.001);
831 
832  // Check momenta 2
833 
834  tot = 0.0;
835 
836  tot += (1.3)*(1.3)*mp4.value(-1.3,0);
837  tot += (0.3)*(0.3)*mp4.value(-0.3,1);
838  tot += (0.7)*(0.7)*mp4.value(0.7,2);
839  tot += (1.7)*(1.7)*mp4.value(1.7,3);
840 
841  BOOST_REQUIRE_SMALL(tot,0.001);
842 
843 
845 
846  tot = 0.0;
847 
848  z_kernel<double,1> zk1;
849 
850  tot += zk1.value(-0.3,0);
851  tot += zk1.value(0.7,1);
852 
853  BOOST_REQUIRE_CLOSE(tot,1.0,0.001);
854 
856 
858 
859  z_kernel<double,3> zk3;
860 
861  tot = 0.0;
862 
863  // Check momenta 0
864 
865  tot += zk3.value(-2.3,0);
866  tot += zk3.value(-1.3,1);
867  tot += zk3.value(-0.3,2);
868  tot += zk3.value(0.7,3);
869  tot += zk3.value(1.7,4);
870  tot += zk3.value(2.7,5);
871 
872  BOOST_REQUIRE_CLOSE(tot,1.0,0.001);
873 
874  // Check momenta 1
875 
876  tot = 0.0;
877 
878  tot += -2.3*zk3.value(-2.3,0);
879  tot += -1.3*zk3.value(-1.3,1);
880  tot += -0.3*zk3.value(-0.3,2);
881  tot += 0.7*zk3.value(0.7,3);
882  tot += 1.7*zk3.value(1.7,4);
883  tot += 2.7*zk3.value(2.7,5);
884 
885  BOOST_REQUIRE_SMALL(tot,0.001);
886 
887  // Check momenta 2
888 
889  tot = 0.0;
890 
891  tot += 2.3*2.3*zk3.value(-2.3,0);
892  tot += 1.3*1.3*zk3.value(-1.3,1);
893  tot += 0.3*0.3*zk3.value(-0.3,2);
894  tot += 0.7*0.7*zk3.value(0.7,3);
895  tot += 1.7*1.7*zk3.value(1.7,4);
896  tot += 2.7*2.7*zk3.value(2.7,5);
897 
898  BOOST_REQUIRE_SMALL(tot,0.001);
899 
900  // Check momenta 3
901 
902  tot = 0.0;
903 
904  tot += -2.3*-2.3*-2.3*zk3.value(-2.3,0);
905  tot += -1.3*-1.3*-1.3*zk3.value(-1.3,1);
906  tot += -0.3*-0.3*-0.3*zk3.value(-0.3,2);
907  tot += 0.7*0.7*0.7*zk3.value(0.7,3);
908  tot += 1.7*1.7*1.7*zk3.value(1.7,4);
909  tot += 2.7*2.7*2.7*zk3.value(2.7,5);
910 
911  BOOST_REQUIRE_SMALL(tot,0.001);
912 
913 
914  // z4
915 
916  z_kernel<double,4> zk4;
917 
918  // Check momenta 0
919 
920  tot = 0.0;
921 
922  tot += zk4.value(-3.3,0);
923  tot += zk4.value(-2.3,1);
924  tot += zk4.value(-1.3,2);
925  tot += zk4.value(-0.3,3);
926  tot += zk4.value(0.7,4);
927  tot += zk4.value(1.7,5);
928  tot += zk4.value(2.7,6);
929  tot += zk4.value(3.7,7);
930 
931  BOOST_REQUIRE_CLOSE(tot,1.0,0.001);
932 
933  // Check momenta 1
934 
935  tot = 0.0;
936 
937  tot += -3.3*zk4.value(-3.3,0);
938  tot += -2.3*zk4.value(-2.3,1);
939  tot += -1.3*zk4.value(-1.3,2);
940  tot += -0.3*zk4.value(-0.3,3);
941  tot += 0.7*zk4.value(0.7,4);
942  tot += 1.7*zk4.value(1.7,5);
943  tot += 2.7*zk4.value(2.7,6);
944  tot += 3.7*zk4.value(3.7,7);
945 
946  BOOST_REQUIRE_SMALL(tot,0.001);
947 
948  // Check momenta 2
949 
950  tot = 0.0;
951 
952  tot += 3.3*3.3*zk4.value(-3.3,0);
953  tot += 2.3*2.3*zk4.value(-2.3,1);
954  tot += 1.3*1.3*zk4.value(-1.3,2);
955  tot += 0.3*0.3*zk4.value(-0.3,3);
956  tot += 0.7*0.7*zk4.value(0.7,4);
957  tot += 1.7*1.7*zk4.value(1.7,5);
958  tot += 2.7*2.7*zk4.value(2.7,6);
959  tot += 3.7*3.7*zk4.value(3.7,7);
960 
961  BOOST_REQUIRE_SMALL(tot,0.001);
962 
963  // Check momenta 3
964 
965  tot = 0.0;
966 
967  tot += -3.3*-3.3*-3.3*zk4.value(-3.3,0);
968  tot += -2.3*-2.3*-2.3*zk4.value(-2.3,1);
969  tot += -1.3*-1.3*-1.3*zk4.value(-1.3,2);
970  tot += -0.3*-0.3*-0.3*zk4.value(-0.3,3);
971  tot += 0.7*0.7*0.7*zk4.value(0.7,4);
972  tot += 1.7*1.7*1.7*zk4.value(1.7,5);
973  tot += 2.7*2.7*2.7*zk4.value(2.7,6);
974  tot += 3.7*3.7*3.7*zk4.value(3.7,7);
975 
976  BOOST_REQUIRE_SMALL(tot,0.001);
977 
978  // Check momenta 4
979 
980  tot = 0.0;
981 
982  tot += -3.3*-3.3*-3.3*-3.3*zk4.value(-3.3,0);
983  tot += -2.3*-2.3*-2.3*-2.3*zk4.value(-2.3,1);
984  tot += -1.3*-1.3*-1.3*-1.3*zk4.value(-1.3,2);
985  tot += -0.3*-0.3*-0.3*-0.3*zk4.value(-0.3,3);
986  tot += 0.7*0.7*0.7*0.7*zk4.value(0.7,4);
987  tot += 1.7*1.7*1.7*1.7*zk4.value(1.7,5);
988  tot += 2.7*2.7*2.7*2.7*zk4.value(2.7,6);
989  tot += 3.7*3.7*3.7*3.7*zk4.value(3.7,7);
990 
991  BOOST_REQUIRE_SMALL(tot,0.001);
992 }
993 
994 /*
995 BOOST_AUTO_TEST_CASE(InterpolationConvergenceP2M)
996 {
997  size_t res;
998  std::cout<<"Enter Res:";
999  std::cin>>res;
1000  const size_t sz[2] = {res,res};
1001  Box<2, double> box({0, 0}, {2 * M_PI, 2 * M_PI});
1002  size_t bc[2] = {PERIODIC, PERIODIC};
1003  double spacing[2];
1004  spacing[0] = 2 *M_PI / (sz[0]);
1005  spacing[1] = 2 *M_PI / (sz[1]);
1006  Ghost<2,long int> gg(3);
1007  double rCut = 3.0 * spacing[0];
1008  Ghost<2, double> ghost(rCut);
1009 
1010  vector_dist<2, double, aggregate<double, double>> particles(0, box,bc,ghost);
1011  grid_dist_id<2, double, aggregate<double, double>> gd(particles.getDecomposition(),sz,gg);
1012  double sigma2 = spacing[0] / (40.0);
1013  std::normal_distribution<> gaussian{0, sigma2};
1014  std::mt19937 rng{6666666};
1015  auto it = particles.getGridIterator(sz);
1016  while (it.isNext()) {
1017  particles.add();
1018  auto key = it.get();
1019  double x=key.get(0) * spacing[0] + gaussian(rng);
1020  double y=key.get(1) * spacing[1] + gaussian(rng);
1021  particles.getLastPos()[0] = x;
1022  particles.getLastPos()[1] = y;
1023  // Here fill the function value
1024  particles.template getLastProp<0>() = sin(particles.getLastPos()[0]) + sin(particles.getLastPos()[0]);
1025  ++it;
1026  }
1027  particles.map();
1028  particles.ghost_get<0>();
1029 
1030  auto itG=gd.getDomainIterator();
1031  while(itG.isNext())
1032  {
1033  auto key=itG.get();
1034  gd.template getProp<1>(key) = sin(gd.getPos(key)[0]) + sin(gd.getPos(key)[0]);
1035  ++itG;
1036  }
1037 
1038  particles.write("InitP");
1039  gd.write("Grid");
1040 
1041  auto Pu=getV<0>(particles);
1042  auto Gu=FD::getV<0>(gd);
1043  typedef vector_dist<2, double, aggregate<double, double>> particle_type;
1044  typedef grid_dist_id<2, double, aggregate<double, double>> gd_type;
1045  typedef z_kernel<double,4> kerneltype; //mp4_kernel<double>
1046  typedef lambda4_4kernel<double> kerneltype2;
1047  interpolate<particle_type,gd_type,kerneltype2> inte2m(particles,gd);
1048  Gu=0;
1049  gd.ghost_get<0>();
1050  inte2m.template p2m<0,0>(particles,gd);
1051  gd.template ghost_put<add_,0>();
1052  gd.ghost_get<0>();
1053  particles.write("InitPAfter");
1054  gd.write("GridAfter");
1055 
1056 
1057  auto it2 = gd.getDomainIterator();
1058  double worst = 0.0;
1059  while (it2.isNext()) {
1060  auto p = it2.get();
1061  if (fabs(gd.template getProp<1>(p) - gd.template getProp<0>(p)) > worst) {
1062  worst = fabs(gd. template getProp<1>(p) - gd.template getProp<0>(p));
1063  }
1064  ++it2;
1065  }
1066  std::cout<<worst<<std::endl;
1067  //BOOST_REQUIRE(worst < 0.03);
1068 }
1069 
1070 BOOST_AUTO_TEST_CASE(InterpolationConvergenceM2P)
1071 {
1072  size_t res;
1073  std::cout<<"Enter Res:";
1074  std::cin>>res;
1075  const size_t sz[2] = {res,res};
1076  Box<2, double> box({0, 0}, {2 * M_PI, 2 * M_PI});
1077  size_t bc[2] = {PERIODIC, PERIODIC};
1078  double spacing[2];
1079  spacing[0] = 2 *M_PI / (sz[0]);
1080  spacing[1] = 2 *M_PI / (sz[1]);
1081  Ghost<2,long int> gg(3);
1082  double rCut = 3.0 * spacing[0];
1083  Ghost<2, double> ghost(rCut);
1084 
1085  vector_dist<2, double, aggregate<double, double>> particles(0, box,bc,ghost);
1086  grid_dist_id<2, double, aggregate<double, double>> gd(particles.getDecomposition(),sz,gg);
1087  double sigma2 = spacing[0] * spacing[1];
1088  std::normal_distribution<> gaussian{0, sigma2};
1089  std::mt19937 rng{6666666};
1090  auto it = particles.getGridIterator(sz);
1091  while (it.isNext()) {
1092  particles.add();
1093  auto key = it.get();
1094  double x=key.get(0) * spacing[0] + gaussian(rng);
1095  double y=key.get(1) * spacing[1] + gaussian(rng);
1096  particles.getLastPos()[0] = x;
1097  particles.getLastPos()[1] = y;
1098  // Here fill the function value
1099  particles.template getLastProp<0>() = 0;
1100  particles.template getLastProp<1>() = sin(particles.getLastPos()[0]) + sin(particles.getLastPos()[0]);
1101  ++it;
1102  }
1103  particles.map();
1104  particles.ghost_get<0>();
1105 
1106  auto itG=gd.getDomainIterator();
1107  while(itG.isNext())
1108  {
1109  auto key=itG.get();
1110  gd.template getProp<1>(key) = sin(gd.getPos(key)[0]) + sin(gd.getPos(key)[0]);
1111  ++itG;
1112  }
1113 
1114  particles.write("InitP");
1115  gd.write("Grid");
1116 
1117  auto Pu=getV<0>(particles);
1118  auto Gu=FD::getV<0>(gd);
1119  typedef vector_dist<2, double, aggregate<double, double>> particle_type;
1120  typedef grid_dist_id<2, double, aggregate<double, double>> gd_type;
1121  typedef z_kernel<double,4> kerneltype; //mp4_kernel<double>
1122  typedef lambda4_4kernel<double> kerneltype2;
1123  interpolate<particle_type,gd_type,kerneltype2> inte2m(particles,gd);
1124  Gu=0;
1125  gd.ghost_get<0>();
1126  inte2m.template m2p<1,0>(gd,particles);
1127  particles.ghost_get<0>();
1128  particles.write("InitPAfter");
1129  gd.write("GridAfter");
1130 
1131  auto it2 = particles.getDomainIterator();
1132 
1133  double worst = 0.0;
1134  while (it2.isNext()) {
1135  auto p = it2.get();
1136  if (fabs(particles.template getProp<1>(p) - particles.template getProp<0>(p)) > worst) {
1137  worst = fabs(particles. template getProp<1>(p) - particles.template getProp<0>(p));
1138  }
1139  ++it2;
1140  }
1141  std::cout<<worst<<std::endl;
1142  //BOOST_REQUIRE(worst < 0.03);
1143 
1144 }
1145 
1146 
1147 
1148 BOOST_AUTO_TEST_CASE(InterpolationMoving)
1149 {
1150 
1151  size_t res;
1152  std::cin>>res;
1153  const size_t sz[2] = {res,res};
1154  Box<2, double> box({0, 0}, {2 * M_PI, 2 * M_PI});
1155  size_t bc[2] = {PERIODIC, PERIODIC};
1156  double spacing[2];
1157  spacing[0] = 2 *M_PI / (sz[0]);
1158  spacing[1] = 2 *M_PI / (sz[1]);
1159  Ghost<2,long int> gg(3);
1160  double rCut = 3.0 * spacing[0];
1161  Ghost<2, double> ghost(rCut);
1162 
1163  vector_dist<2, double, aggregate<double, VectorS<2, double>>> particles(0, box,bc,ghost),particlesMoved(0, box,bc,ghost);
1164  grid_dist_id<2, double, aggregate<double, VectorS<2, double>>> gd(particles.getDecomposition(),sz,gg);
1165 
1166  auto it = particles.getGridIterator(sz);
1167  while (it.isNext()) {
1168  particles.add();
1169  auto key = it.get();
1170  double x=key.get(0) * spacing[0];
1171  double y=key.get(1) * spacing[1];
1172  particles.getLastPos()[0] = x;
1173  particles.getLastPos()[1] = y;
1174  // Here fill the function value
1175  particles.template getLastProp<1>() = 1.0;
1176  particles.template getLastProp<1>() = 0;
1177  particles.template getLastProp<0>() = 0;
1178  if((x-3.14)*(x-3.14)+(y-3.14)*(y-3.14)<1)
1179  {
1180  particles.template getLastProp<0>() = 1;
1181  }
1182  ++it;
1183  }
1184  particles.map();
1185  particles.ghost_get<0>();
1186 
1187  particles.write("InitP");
1188  gd.write("Grid");
1189 
1190  auto Pu=getV<0>(particles);
1191  auto Pmu=getV<0>(particlesMoved);
1192  auto Gu=FD::getV<0>(gd);
1193  typedef vector_dist<2, double, aggregate<double, VectorS<2, double>>> vd;
1194  typedef grid_dist_id<2, double, aggregate<double, VectorS<2, double>>> gd_type;
1195  interpolate<vd,gd_type,mp4_kernel<double>> inte2m(particlesMoved,gd);
1196  interpolate<vd,gd_type,mp4_kernel<double>> inte2p(particles,gd);
1197  double t=0,dt=0.5;
1198  int ctr=0;
1199  while(t<10)
1200  {
1201  particlesMoved.clear();
1202  auto it=particles.getDomainIterator();
1203  while(it.isNext())
1204  {
1205  auto p=it.get();
1206  double xp=particles.getPos(p)[0],yp=particles.getPos(p)[1];
1207  particlesMoved.add();
1208  particlesMoved.getLastPos()[0] = xp+dt*particles.getProp<1>(p)[0];
1209  particlesMoved.getLastPos()[1] = yp+dt*particles.getProp<1>(p)[1];
1210  particlesMoved.getLastProp<0>() = particles.getProp<0>(p);
1211  ++it;
1212  }
1213  particlesMoved.map();
1214  particlesMoved.ghost_get<0>();
1215  Gu=0;
1216  gd.ghost_get<0>();
1217  inte2m.template p2m<0,0>(particlesMoved,gd);
1218  gd.template ghost_put<add_,0>();
1219  gd.ghost_get<0>();
1220  Pu=0;
1221  inte2p.template m2p<0,0>(gd,particles);
1222  particles.write_frame("InitP",ctr);
1223  gd.write_frame("Grid",ctr);
1224  ctr++;
1225  t+=dt;
1226  }*/
1227 
1228 /*
1229 
1230  auto it2 = domain.getDomainIterator();
1231 
1232  double worst = 0.0;
1233 
1234  while (it2.isNext()) {
1235  auto p = it2.get();
1236  if (fabs(domain.getProp<1>(p) - domain.getProp<2>(p)) > worst) {
1237  worst = fabs(domain.getProp<1>(p) - domain.getProp<2>(p));
1238  }
1239  ++it2;
1240  }
1241 */
1242 
1243  // domain.deleteGhost();
1244  // BOOST_REQUIRE(worst < 0.03);
1245 
1246 //}
1247 BOOST_AUTO_TEST_SUITE_END()
1248 
1249 
1250 #endif /* OPENFPM_NUMERICS_SRC_INTERPOLATION_INTERPOLATION_UNIT_TESTS_HPP_ */
This class represent an N-dimensional box.
Definition: Box.hpp:60
Definition: Ghost.hpp:40
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
This is a distributed grid.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:19
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
Main class for interpolation Particle to mest p2m and Mesh to particle m2p.
Distributed vector.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data