OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
grid_dist_id.hpp
1 #ifndef COM_UNIT_HPP
2 #define COM_UNIT_HPP
3 
4 #include <vector>
5 #include <unordered_map>
6 #include "Grid/map_grid.hpp"
7 #include "VCluster/VCluster.hpp"
8 #include "Space/SpaceBox.hpp"
9 #include "util/mathutil.hpp"
10 #include "VTKWriter/VTKWriter.hpp"
11 #ifdef __NVCC__
12 #include "SparseGridGpu/SparseGridGpu.hpp"
13 #endif
14 #include "Iterators/grid_dist_id_iterator_dec.hpp"
15 #include "Iterators/grid_dist_id_iterator.hpp"
16 #include "Iterators/grid_dist_id_iterator_sub.hpp"
17 #include "grid_dist_key.hpp"
18 #include "NN/CellList/CellDecomposer.hpp"
19 #include "util/object_util.hpp"
20 #include "memory/ExtPreAlloc.hpp"
21 #include "Packer_Unpacker/Packer.hpp"
22 #include "Packer_Unpacker/Unpacker.hpp"
23 #include "Decomposition/CartDecomposition.hpp"
24 #include "data_type/aggregate.hpp"
25 #include "hdf5.h"
26 #include "grid_dist_id_comm.hpp"
27 #include "HDF5_wr/HDF5_wr.hpp"
28 #include "SparseGrid/SparseGrid.hpp"
29 #include "lib/pdata.hpp"
30 #ifdef __NVCC__
31 #include "cuda/grid_dist_id_kernels.cuh"
32 #include "Grid/cuda/grid_dist_id_iterator_gpu.cuh"
33 #endif
34 
38 template<unsigned int dim>
39 struct offset_mv
40 {
43 
46 };
47 
49 template<unsigned int dim>
50 struct Box_fix
51 {
57  size_t g_id;
59  size_t r_sub;
60 };
61 
62 #define NO_GDB_EXT_SWITCH 0x1000
63 
90 template<unsigned int dim,
91  typename St,
92  typename T,
94  typename Memory=HeapMemory ,
95  typename device_grid=grid_cpu<dim,T> >
96 class grid_dist_id : public grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>
97 {
99 
102 
105 
108 
111 
114 
117 
128 
131 
134 
137 
139  size_t g_sz[dim];
140 
142  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
143 
146 
149 
152 
155  std::unordered_map<size_t,size_t> g_id_to_external_ghost_box;
156 
226 
230 
233 
236 
239 
242 
245 
247  bool use_bx_def = false;
248 
250  bool init_local_i_g_box = false;
251 
253  bool init_local_e_g_box = false;
254 
256  bool init_e_g_box = false;
257 
259  bool init_i_g_box = false;
260 
262  bool init_fix_ie_g_box = false;
263 
266 
269 
272 
275 
277  size_t v_sub_unit_factor = 64;
278 
290  static void * msg_alloc_external_box(size_t msg_i ,size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr)
291  {
293 
294  g->recv_sz.resize(g->dec.getNNProcessors());
295  g->recv_mem_gg.resize(g->dec.getNNProcessors());
296 
297  // Get the local processor id
298  size_t lc_id = g->dec.ProctoID(i);
299 
300  // resize the receive buffer
301  g->recv_mem_gg.get(lc_id).resize(msg_i);
302  g->recv_sz.get(lc_id) = msg_i;
303 
304  return g->recv_mem_gg.get(lc_id).getPointer();
305  }
306 
319  void set_for_adjustment(size_t sub_id,
320  const Box<dim,St> & sub_domain_other,
321  const comb<dim> & cmb,
322  Box<dim,long int> & ib,
324  {
325  if (g.isInvalidGhost() == true || use_bx_def == true)
326  {return;}
327 
328  Box<dim,long int> sub_domain;
329 
330  if (use_bx_def == false)
331  {
332  sub_domain = gdb_ext.get(sub_id).Dbox;
333  sub_domain += gdb_ext.get(sub_id).origin;
334  }
335 
336  // Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
337  Box<dim,long int> sub_domain_other_exp = cd_sm.convertDomainSpaceIntoGridUnits(sub_domain_other,dec.periodicity());
338 
339  // translate sub_domain_other based on cmb
340  for (size_t i = 0 ; i < dim ; i++)
341  {
342  if (cmb.c[i] == 1)
343  {
344  sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) - ginfo.size(i));
345  sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) - ginfo.size(i));
346  }
347  else if (cmb.c[i] == -1)
348  {
349  sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) + ginfo.size(i));
350  sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) + ginfo.size(i));
351  }
352  }
353 
354  sub_domain_other_exp.enlarge(g);
355  if (sub_domain_other_exp.Intersect(sub_domain,ib) == false)
356  {
357  for (size_t i = 0 ; i < dim ; i++)
358  {ib.setHigh(i,ib.getLow(i) - 1);}
359  }
360  }
361 
362 
363 
368  {
369  // temporal vector used for computation
371 
372  if (init_i_g_box == true) return;
373 
374  // Get the grid info
375  auto g = cd_sm.getGrid();
376 
377  g_id_to_internal_ghost_box.resize(dec.getNNProcessors());
378 
379  // Get the number of near processors
380  for (size_t i = 0 ; i < dec.getNNProcessors() ; i++)
381  {
382  ig_box.add();
383  auto&& pib = ig_box.last();
384 
385  pib.prc = dec.IDtoProc(i);
386  for (size_t j = 0 ; j < dec.getProcessorNIGhost(i) ; j++)
387  {
388  // Get the internal ghost boxes and transform into grid units
389  ::Box<dim,St> ib_dom = dec.getProcessorIGhostBox(i,j);
390  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
391 
392  size_t sub_id = dec.getProcessorIGhostSub(i,j);
393  size_t r_sub = dec.getProcessorIGhostSSub(i,j);
394 
395  auto & n_box = dec.getNearSubdomains(dec.IDtoProc(i));
396 
397  set_for_adjustment(sub_id,
398  n_box.get(r_sub),dec.getProcessorIGhostPos(i,j),
399  ib,ghost_int);
400 
401  // Here we intersect the internal ghost box with the definition boxes
402  // this operation make sense when the grid is not defined in the full
403  // domain and we have to intersect the internal ghost box with all the box
404  // that define where the grid is defined
405  bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
406 
407  for (size_t k = 0 ; k < ibv.size() ; k++)
408  {
409  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
410  if (ibv.get(k).bx.isValid() == false)
411  {continue;}
412 
413  // save the box and the sub-domain id (it is calculated as the linearization of P1)
414  ::Box<dim,size_t> cvt = ibv.get(k).bx;
415 
416  i_box_id<dim> bid_t;
417  bid_t.box = cvt;
418  bid_t.g_id = dec.getProcessorIGhostId(i,j) | (k) << 52;
419 
420  bid_t.sub = convert_to_gdb_ext(dec.getProcessorIGhostSub(i,j),
421  ibv.get(k).id,
422  gdb_ext,
424 
425  bid_t.cmb = dec.getProcessorIGhostPos(i,j);
426  bid_t.r_sub = dec.getProcessorIGhostSSub(i,j);
427  pib.bid.add(bid_t);
428 
429  g_id_to_internal_ghost_box.get(i)[bid_t.g_id | (k) << 52 ] = pib.bid.size()-1;
430  }
431  }
432  }
433 
434  init_i_g_box = true;
435  }
436 
437 
442  {
443  // Get the grid info
444  auto g = cd_sm.getGrid();
445 
446  if (init_e_g_box == true) return;
447 
448  // Here we collect all the calculated internal ghost box in the sector different from 0 that this processor has
449 
451  openfpm::vector<size_t> prc_recv;
452  openfpm::vector<size_t> sz_recv;
453  openfpm::vector<openfpm::vector<Box_fix<dim>>> box_int_send(dec.getNNProcessors());
455 
456  for(size_t i = 0 ; i < dec.getNNProcessors() ; i++)
457  {
458  for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
459  {
460  box_int_send.get(i).add();
461  box_int_send.get(i).last().bx = ig_box.get(i).bid.get(j).box;
462  box_int_send.get(i).last().g_id = ig_box.get(i).bid.get(j).g_id;
463  box_int_send.get(i).last().r_sub = ig_box.get(i).bid.get(j).r_sub;
464  box_int_send.get(i).last().cmb = ig_box.get(i).bid.get(j).cmb;
465  }
466  prc.add(dec.IDtoProc(i));
467  }
468 
469  v_cl.SSendRecv(box_int_send,box_int_recv,prc,prc_recv,sz_recv);
470 
471  eg_box.resize(dec.getNNProcessors());
472 
473  for (size_t i = 0 ; i < eg_box.size() ; i++)
474  {eg_box.get(i).prc = dec.IDtoProc(i);}
475 
476  for (size_t i = 0 ; i < box_int_recv.size() ; i++)
477  {
478  size_t pib_cnt = 0;
479  size_t p_id = dec.ProctoID(prc_recv.get(i));
480  auto&& pib = eg_box.get(p_id);
481  pib.prc = prc_recv.get(i);
482 
483  eg_box.get(p_id).recv_pnt = 0;
484  eg_box.get(p_id).n_r_box = box_int_recv.get(i).size();
485 
486  // For each received internal ghost box
487  for (size_t j = 0 ; j < box_int_recv.get(i).size() ; j++)
488  {
489  size_t vol_recv = box_int_recv.get(i).get(j).bx.getVolumeKey();
490 
491  eg_box.get(p_id).recv_pnt += vol_recv;
492  size_t send_list_id = box_int_recv.get(i).get(j).r_sub;
493 
494  if (use_bx_def == true)
495  {
496  // First we understand if the internal ghost box sent intersect
497  // some local extended sub-domain.
498 
499  // eb_gid_list, for an explanation check the declaration
500  eb_gid_list.add();
501  eb_gid_list.last().e_id = p_id;
502 
503  // Now we have to check if a received external ghost box intersect one
504  // or more sub-grids
505  for (size_t k = 0 ; k < gdb_ext.size() ; k++)
506  {
507  Box<dim,long int> bx = gdb_ext.get(k).GDbox;
508  bx += gdb_ext.get(k).origin;
509 
510  Box<dim,long int> output;
511  Box<dim,long int> flp_i = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
512 
513  // it intersect one sub-grid
514  if (bx.Intersect(flp_i,output))
515  {
516  // link
517 
518  size_t g_id = box_int_recv.get(i).get(j).g_id;
519  add_eg_box<dim>(k,box_int_recv.get(i).get(j).cmb,output,
520  g_id,
521  gdb_ext.get(k).origin,
522  box_int_recv.get(i).get(j).bx.getP1(),
523  pib.bid);
524 
525  eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
526 
528  }
529  }
530 
531  // now we check if exist a full match across the full intersected
532  // ghost parts
533 
534  bool no_match = true;
535  for (size_t k = 0 ; k < eb_gid_list.last().eb_list.size() ; k++)
536  {
537  size_t eb_id = eb_gid_list.last().eb_list.get(k);
538 
539  if (pib.bid.get(eb_id).g_e_box == box_int_recv.get(i).get(j).bx)
540  {
541  // full match found
542 
543  eb_gid_list.last().full_match = eb_id;
544  no_match = false;
545 
546  break;
547  }
548  }
549 
550  // This is the case where a full match has not been found. In this case we
551  // generate an additional gdb_ext and local grid with only external ghost
552 
553  if (no_match == true)
554  {
555  // Create a grid with the same size of the external ghost
556 
557  size_t sz[dim];
558  for (size_t s = 0 ; s < dim ; s++)
559  {sz[s] = box_int_recv.get(i).get(j).bx.getHigh(s) - box_int_recv.get(i).get(j).bx.getLow(s) + 1;}
560 
561  // Add an unlinked gdb_ext
562  // An unlinked gdb_ext is an empty domain with only a external ghost
563  // part
564  Box<dim,long int> output = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
565 
566  GBoxes<dim> tmp;
567  tmp.GDbox = box_int_recv.get(i).get(j).bx;
568  tmp.GDbox -= tmp.GDbox.getP1();
569  tmp.origin = output.getP1();
570  for (size_t s = 0 ; s < dim ; s++)
571  {
572  // we set an invalid box, there is no-domain
573  tmp.Dbox.setLow(s,0);
574  tmp.Dbox.setHigh(s,-1);
575  }
576  tmp.k = (size_t)-1;
577  gdb_ext.add(tmp);
578 
579  // create the local grid
580 
581  loc_grid.add();
582  loc_grid.last().resize(sz);
583 
584  // Add an external ghost box
585 
586  size_t g_id = box_int_recv.get(i).get(j).g_id;
587  add_eg_box<dim>(gdb_ext.size()-1,box_int_recv.get(i).get(j).cmb,output,
588  g_id,
589  gdb_ext.get(gdb_ext.size()-1).origin,
590  box_int_recv.get(i).get(j).bx.getP1(),
591  pib.bid);
592 
593  // now we map the received ghost box to the information of the
594  // external ghost box created
595  eb_gid_list.last().full_match = pib.bid.size() - 1;
596  eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
598  }
599 
600  // now we create lr_e_box
601 
602  size_t fm = eb_gid_list.last().full_match;
603  size_t sub_id = pib.bid.get(fm).sub;
604 
605  for ( ; pib_cnt < pib.bid.size() ; pib_cnt++)
606  {
607  pib.bid.get(pib_cnt).lr_e_box -= gdb_ext.get(sub_id).origin;
608  }
609 
610  }
611  else
612  {
613  // Get the list of the sent sub-domains
614  // and recover the id of the sub-domain from
615  // the sent list
616  const openfpm::vector<size_t> & s_sub = dec.getSentSubdomains(p_id);
617 
618  size_t sub_id = s_sub.get(send_list_id);
619 
620  e_box_id<dim> bid_t;
621  bid_t.sub = sub_id;
622  bid_t.cmb = box_int_recv.get(i).get(j).cmb;
623  bid_t.cmb.sign_flip();
624  ::Box<dim,long int> ib = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
625  bid_t.g_e_box = ib;
626  bid_t.g_id = box_int_recv.get(i).get(j).g_id;
627  // Translate in local coordinate
628  Box<dim,long int> tb = ib;
629  tb -= gdb_ext.get(sub_id).origin;
630  bid_t.l_e_box = tb;
631 
632  pib.bid.add(bid_t);
633  eb_gid_list.add();
634  eb_gid_list.last().eb_list.add(pib.bid.size()-1);
635  eb_gid_list.last().e_id = p_id;
636  eb_gid_list.last().full_match = pib.bid.size()-1;
637 
639  }
640  }
641  }
642 
643  init_e_g_box = true;
644  }
645 
650  {
652 
653  // Get the grid info
654  auto g = cd_sm.getGrid();
655 
656  if (init_local_i_g_box == true) return;
657 
658  // Get the number of sub-domains
659  for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
660  {
661  loc_ig_box.add();
662  auto&& pib = loc_ig_box.last();
663 
664  for (size_t j = 0 ; j < dec.getLocalNIGhost(i) ; j++)
665  {
666  if (use_bx_def == true)
667  {
668  // Get the internal ghost boxes and transform into grid units
669  ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
670  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
671 
672  // Here we intersect the internal ghost box with the definition boxes
673  // this operation make sense when the grid is not defined in the full
674  // domain and we have to intersect the internal ghost box with all the box
675  // that define where the grid is defined
676  bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
677 
678  for (size_t k = 0 ; k < ibv.size() ; k++)
679  {
680  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
681  if (ibv.get(k).bx.isValid() == false)
682  {continue;}
683 
684  pib.bid.add();
685  pib.bid.last().box = ibv.get(k).bx;
686 
687  pib.bid.last().sub_gdb_ext = convert_to_gdb_ext(i,
688  ibv.get(k).id,
689  gdb_ext,
691 
692  pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
693 
694  // It will be filled later
695  pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
696  }
697  }
698  else
699  {
700  // Get the internal ghost boxes and transform into grid units
701  ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
702  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
703 
704  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
705  if (ib.isValid() == false)
706  continue;
707 
708  size_t sub_id = i;
709  size_t r_sub = dec.getLocalIGhostSub(i,j);
710 
711  set_for_adjustment(sub_id,dec.getSubDomain(r_sub),
712  dec.getLocalIGhostPos(i,j),ib,ghost_int);
713 
714  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
715  if (ib.isValid() == false)
716  continue;
717 
718  pib.bid.add();
719  pib.bid.last().box = ib;
720  pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
721  pib.bid.last().k.add(dec.getLocalIGhostE(i,j));
722  pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
723  pib.bid.last().sub_gdb_ext = i;
724  }
725  }
726 
727  if (use_bx_def == true)
728  {
729  // unfortunately boxes that define where the grid is located can generate
730  // additional internal ghost boxes
731 
732  for (size_t j = gdb_ext_markers.get(i) ; j < gdb_ext_markers.get(i+1) ; j++)
733  {
734  // intersect within box in the save sub-domain
735 
736  for (size_t k = gdb_ext_markers.get(i) ; k < gdb_ext_markers.get(i+1) ; k++)
737  {
738  if (j == k) {continue;}
739 
740  // extend k and calculate the internal ghost box
741  Box<dim,long int> bx_e = gdb_ext.get(k).GDbox;
742  bx_e += gdb_ext.get(k).origin;
743  Box<dim,long int> bx = gdb_ext.get(j).Dbox;
744  bx += gdb_ext.get(j).origin;
745 
746  Box<dim,long int> output;
747  if (bx.Intersect(bx_e, output) == true)
748  {
749  pib.bid.add();
750 
751  pib.bid.last().box = output;
752 
753  pib.bid.last().sub_gdb_ext = j;
754  pib.bid.last().sub = i;
755 
756  // these ghost always in the quadrant zero
757  pib.bid.last().cmb.zero();
758 
759  }
760  }
761  }
762  }
763 
764  }
765 
766 
767  init_local_i_g_box = true;
768  }
769 
774  {
775  // Get the grid info
776  auto g = cd_sm.getGrid();
777 
778  if (init_local_e_g_box == true) return;
779 
780  loc_eg_box.resize(dec.getNSubDomain());
781 
782  // Get the number of sub-domain
783  for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
784  {
785  for (size_t j = 0 ; j < loc_ig_box.get(i).bid.size() ; j++)
786  {
787  long int volume_linked = 0;
788 
789  size_t le_sub = loc_ig_box.get(i).bid.get(j).sub;
790  auto & pib = loc_eg_box.get(le_sub);
791 
792  if (use_bx_def == true)
793  {
794 
795  // We check if an external local ghost box intersect one
796  // or more sub-grids
797  for (size_t k = 0 ; k < gdb_ext.size() ; k++)
798  {
799  Box<dim,long int> bx = gdb_ext.get(k).Dbox;
800  bx += gdb_ext.get(k).origin;
801 
802  Box<dim,long int> gbx = gdb_ext.get(k).GDbox;
803  gbx += gdb_ext.get(k).origin;
804 
805  Box<dim,long int> output;
806  Box<dim,long int> flp_i = flip_box(loc_ig_box.get(i).bid.get(j).box,loc_ig_box.get(i).bid.get(j).cmb,ginfo);
807 
808  bool intersect_domain = bx.Intersect(flp_i,output);
809  bool intersect_gdomain = gbx.Intersect(flp_i,output);
810 
811  // it intersect one sub-grid
812  if (intersect_domain == false && intersect_gdomain == true)
813  {
814  // fill the link variable
815  loc_ig_box.get(i).bid.get(j).k.add(pib.bid.size());
816  size_t s = loc_ig_box.get(i).bid.get(j).k.last();
817 
818  comb<dim> cmb = loc_ig_box.get(i).bid.get(j).cmb;
819  cmb.sign_flip();
820 
821  add_loc_eg_box(le_sub,
822  loc_ig_box.get(i).bid.get(j).sub_gdb_ext,
823  j,
824  k,
825  pib.bid,
826  output,
827  cmb);
828 
829 
830  volume_linked += pib.bid.last().ebox.getVolumeKey();
831  }
832  }
833  }
834  else
835  {
836  size_t k = loc_ig_box.get(i).bid.get(j).sub;
837  auto & pib = loc_eg_box.get(k);
838 
839  size_t s = loc_ig_box.get(i).bid.get(j).k.get(0);
840  pib.bid.resize(dec.getLocalNEGhost(k));
841 
842  pib.bid.get(s).ebox = flip_box(loc_ig_box.get(i).bid.get(j).box,loc_ig_box.get(i).bid.get(j).cmb,ginfo);
843  pib.bid.get(s).sub = dec.getLocalEGhostSub(k,s);
844  pib.bid.get(s).cmb = loc_ig_box.get(i).bid.get(j).cmb;
845  pib.bid.get(s).cmb.sign_flip();
846  pib.bid.get(s).k = j;
847  pib.bid.get(s).initialized = true;
848  pib.bid.get(s).sub_gdb_ext = k;
849  }
850  }
851  }
852 
853  init_local_e_g_box = true;
854  }
855 
856 
862  inline void check_size(const size_t (& g_sz)[dim])
863  {
864  for (size_t i = 0 ; i < dim ; i++)
865  {
866  if (g_sz[i] < 2)
867  {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " distributed grids with size smaller than 2 are not supported\n";}
868  }
869  }
870 
876  inline void check_domain(const Box<dim,St> & dom)
877  {
878  for (size_t i = 0 ; i < dim ; i++)
879  {
880  if (dom.getLow(i) >= dom.getHigh(i))
881  {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " error the simulation domain is invalid\n";}
882  }
883  }
884 
892  const Ghost<dim,long int> & g,
893  bool use_bx_def)
894  {
895  // create gdb
896  create_gdb_ext<dim,Decomposition>(gdb_ext,gdb_ext_markers,dec,cd_sm,bx_def,g,use_bx_def);
897 
898  size_t n_grid = gdb_ext.size();
899 
900  // create local grids for each hyper-cube
901  loc_grid.resize(n_grid);
902 
903  // Size of the grid on each dimension
904  size_t l_res[dim];
905 
906  // Allocate the grids
907  for (size_t i = 0 ; i < n_grid ; i++)
908  {
909  SpaceBox<dim,long int> sp_tg = gdb_ext.get(i).GDbox;
910 
911  // Get the size of the local grid
912  // The boxes indicate the extension of the index the size
913  // is this extension +1
914  // for example a 1D box (interval) from 0 to 3 in one dimension have
915  // the points 0,1,2,3 = so a total of 4 points
916  for (size_t j = 0 ; j < dim ; j++)
917  {l_res[j] = (sp_tg.getHigh(j) >= 0)?(sp_tg.getHigh(j)+1):0;}
918 
919  // Set the dimensions of the local grid
920  loc_grid.get(i).resize(l_res);
921  }
922  }
923 
924 
931  inline void InitializeCellDecomposer(const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_old, const Box<dim,size_t> & ext)
932  {
933  // Initialize the cell decomposer
934  cd_sm.setDimensions(cd_old,ext);
935  }
936 
943  inline void InitializeCellDecomposer(const size_t (& g_sz)[dim], const size_t (& bc)[dim])
944  {
945  // check that the grid has valid size
946  check_size(g_sz);
947 
948  // get the size of the cell decomposer
949  size_t c_g[dim];
950  getCellDecomposerPar<dim>(c_g,g_sz,bc);
951 
952  // Initialize the cell decomposer
953  cd_sm.setDimensions(domain,c_g,0);
954  }
955 
962  inline void InitializeDecomposition(const size_t (& g_sz)[dim], const size_t (& bc)[dim], const grid_sm<dim,void> & g_dist = grid_sm<dim,void>())
963  {
964  // fill the global size of the grid
965  for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
966 
967  // Get the number of processor and calculate the number of sub-domain
968  // for decomposition
969  size_t n_proc = v_cl.getProcessingUnits();
970  size_t n_sub = n_proc * v_sub_unit_factor;
971 
972  // Calculate the maximum number (before merging) of sub-domain on
973  // each dimension
974  size_t div[dim];
975  for (size_t i = 0 ; i < dim ; i++)
976  {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/dim));}
977 
978  if (g_dist.size(0) != 0)
979  {
980  for (size_t i = 0 ; i < dim ; i++)
981  {div[i] = g_dist.size(i);}
982  }
983 
984  // Create the sub-domains
985  dec.setParameters(div,domain,bc,ghost);
986  dec.decompose(dec_options::DEC_SKIP_ICELL);
987  }
988 
994  inline void InitializeStructures(const size_t (& g_sz)[dim])
995  {
996  // an empty
998 
999  // Ghost zero
1000  Ghost<dim,long int> zero;
1001 
1002  InitializeStructures(g_sz,empty,zero,false);
1003  }
1004 
1012  inline void InitializeStructures(const size_t (& g_sz)[dim],
1014  const Ghost<dim,long int> & g,
1015  bool use_bx_def)
1016  {
1017  // fill the global size of the grid
1018  for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
1019 
1020  // Create local grid
1021  Create(bx,g,use_bx_def);
1022  }
1023 
1024  // Ghost as integer
1026 
1027 protected:
1028 
1037  {
1038  return gdb_ext.get(i).Dbox;
1039  }
1040 
1049  static inline Ghost<dim,St> convert_ghost(const Ghost<dim,long int> & gd, const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_sm)
1050  {
1051  Ghost<dim,St> gc;
1052 
1053  // get the grid spacing
1054  Box<dim,St> sp = cd_sm.getCellBox();
1055 
1056  // enlarge 0.001 of the spacing
1057  sp.magnify_fix_P1(1.1);
1058 
1059  // set the ghost
1060  for (size_t i = 0 ; i < dim ; i++)
1061  {
1062  gc.setLow(i,gd.getLow(i)*(sp.getHigh(i)));
1063  gc.setHigh(i,gd.getHigh(i)*(sp.getHigh(i)));
1064  }
1065 
1066  return gc;
1067  }
1068 
1074  void setDecompositionGranularity(size_t n_sub)
1075  {
1076  this->v_sub_unit_factor = n_sub;
1077  }
1078 
1079  void reset_ghost_structures()
1080  {
1082  ig_box.clear();
1083  init_i_g_box = false;
1084 
1085  eg_box.clear();
1086  eb_gid_list.clear();
1087  init_e_g_box = false;
1088 
1089  init_local_i_g_box = false;
1090  loc_ig_box.clear();
1091 
1092  init_local_e_g_box = false;
1093  loc_eg_box.clear();
1094  }
1095 
1096 public:
1097 
1100 
1103 
1105  typedef T value_type;
1106 
1108  typedef St stype;
1109 
1111  typedef Memory memory_type;
1112 
1115 
1117  static const unsigned int dims = dim;
1118 
1124  inline const Box<dim,St> getDomain() const
1125  {
1126  return domain;
1127  }
1128 
1137  {
1138  return pmul(Point<dim,St>(gdb_ext.get(i).origin), cd_sm.getCellBox().getP2()) + getDomain().getP1();
1139  }
1140 
1148  inline St spacing(size_t i) const
1149  {
1150  return cd_sm.getCellBox().getHigh(i);
1151  }
1152 
1158  size_t size() const
1159  {
1160  return ginfo_v.size();
1161  }
1162 
1169  void setBackgroundValue(T & bv)
1170  {
1171  setBackground_impl<T,decltype(loc_grid)> func(bv,loc_grid);
1172  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop>>(func);
1173  }
1174 
1181  template<unsigned int p>
1182  void setBackgroundValue(const typename boost::mpl::at<typename T::type,boost::mpl::int_<p>>::type & bv)
1183  {
1184  for (size_t i = 0 ; i < loc_grid.size() ; i++)
1185  {loc_grid.get(i).template setBackgroundValue<p>(bv);}
1186  }
1187 
1196  size_t size_local_inserted() const
1197  {
1198  size_t lins = 0;
1199 
1200  for (size_t i = 0 ; i < loc_grid.size() ; i++)
1201  {lins += loc_grid.get(i).size_inserted();}
1202 
1203  return lins;
1204  }
1205 
1213  size_t size(size_t i) const
1214  {
1215  return ginfo_v.size(i);
1216  }
1217 
1224  :grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>(g),
1225  domain(g.domain),
1226  ghost(g.ghost),
1227  ghost_int(g.ghost_int),
1228  loc_grid(g.loc_grid),
1230  dec(g.dec),
1232  gdb_ext(g.gdb_ext),
1235  cd_sm(g.cd_sm),
1236  v_cl(g.v_cl),
1237  prp_names(g.prp_names),
1240  ginfo(g.ginfo),
1241  ginfo_v(g.ginfo_v),
1244  {
1245 #ifdef SE_CLASS2
1246  check_new(this,8,GRID_DIST_EVENT,4);
1247 #endif
1248 
1249  for (size_t i = 0 ; i < dim ; i++)
1250  {g_sz[i] = g.g_sz[i];}
1251  }
1252 
1263  template<typename H>
1264  grid_dist_id(const grid_dist_id<dim,St,H,typename Decomposition::base_type,Memory,grid_cpu<dim,H>> & g,
1265  const Ghost<dim,long int> & gh,
1266  Box<dim,size_t> ext)
1267  :ghost_int(gh),dec(create_vcluster()),v_cl(create_vcluster())
1268  {
1269 #ifdef SE_CLASS2
1270  check_new(this,8,GRID_DIST_EVENT,4);
1271 #endif
1272 
1273  size_t ext_dim[dim];
1274  for (size_t i = 0 ; i < dim ; i++) {ext_dim[i] = g.getGridInfoVoid().size(i) + ext.getKP1().get(i) + ext.getKP2().get(i);}
1275 
1276  // Set the grid info of the extended grid
1277  ginfo.setDimensions(ext_dim);
1278  ginfo_v.setDimensions(ext_dim);
1279 
1280  InitializeCellDecomposer(g.getCellDecomposer(),ext);
1281 
1282  ghost = convert_ghost(gh,cd_sm);
1283 
1284  // Extend the grid by the extension part and calculate the domain
1285 
1286  for (size_t i = 0 ; i < dim ; i++)
1287  {
1288  g_sz[i] = g.size(i) + ext.getLow(i) + ext.getHigh(i);
1289 
1290  if (g.getDecomposition().periodicity(i) == NON_PERIODIC)
1291  {
1292  this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i) - g.spacing(i) / 2.0);
1293  this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i) + g.spacing(i) / 2.0);
1294  }
1295  else
1296  {
1297  this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i));
1298  this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i));
1299  }
1300  }
1301 
1302  dec.setParameters(g.getDecomposition(),ghost,this->domain);
1303 
1304  // an empty
1306 
1307  InitializeStructures(g.getGridInfoVoid().getSize(),empty,gh,false);
1308  }
1309 
1317  template<typename Decomposition2>
1318  grid_dist_id(const Decomposition2 & dec,
1319  const size_t (& g_sz)[dim],
1320  const Ghost<dim,St> & ghost)
1321  :domain(dec.getDomain()),ghost(ghost),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),
1323  {
1324 #ifdef SE_CLASS2
1325  check_new(this,8,GRID_DIST_EVENT,4);
1326 #endif
1327 
1328  InitializeCellDecomposer(g_sz,dec.periodicity());
1329 
1330  this->dec = dec.duplicate(ghost);
1331 
1333  }
1334 
1342  grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1343  const Ghost<dim,St> & ghost)
1345  ginfo_v(g_sz),v_cl(create_vcluster()),ghost_int(INVALID_GHOST)
1346  {
1347 #ifdef SE_CLASS2
1348  check_new(this,8,GRID_DIST_EVENT,4);
1349 #endif
1350 
1351  InitializeCellDecomposer(g_sz,dec.periodicity());
1352 
1353  this->dec = dec.duplicate(ghost);
1354 
1356  }
1357 
1367  grid_dist_id(const Decomposition & dec, const size_t (& g_sz)[dim],
1368  const Ghost<dim,long int> & g)
1369  :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1371  {
1372  InitializeCellDecomposer(g_sz,dec.periodicity());
1373 
1374  ghost = convert_ghost(g,cd_sm);
1375  this->dec = dec.duplicate(ghost);
1376 
1377  // an empty
1379 
1380  // Initialize structures
1381  InitializeStructures(g_sz,empty,g,false);
1382  }
1383 
1393  template<typename Decomposition2>
1394  grid_dist_id(const Decomposition2 & dec, const size_t (& g_sz)[dim],
1395  const Ghost<dim,long int> & g)
1396  :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1398  {
1399  InitializeCellDecomposer(g_sz,dec.periodicity());
1400 
1401  ghost = convert_ghost(g,cd_sm);
1402  this->dec = dec.duplicate(ghost);
1403 
1404  // an empty
1406 
1407  // Initialize structures
1408  InitializeStructures(g_sz,empty,g,false);
1409  }
1410 
1420  grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1421  const Ghost<dim,long int> & g)
1422  :domain(dec.getDomain()),dec(dec),v_cl(create_vcluster()),ginfo(g_sz),
1423  ginfo_v(g_sz),ghost_int(g)
1424  {
1425 #ifdef SE_CLASS2
1426  check_new(this,8,GRID_DIST_EVENT,4);
1427 #endif
1428  InitializeCellDecomposer(g_sz,dec.periodicity());
1429 
1430  ghost = convert_ghost(g,cd_sm);
1431  this->dec = dec.duplicate(ghost);
1432 
1433  // an empty
1435 
1436  // Initialize structures
1437  InitializeStructures(g_sz,empty,g,false);
1438  }
1439 
1449  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g, size_t opt = 0)
1450  :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1451  {
1452  }
1453 
1463  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g, size_t opt = 0)
1464  :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1465  {
1466  }
1467 
1478  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g, const periodicity<dim> & p, size_t opt = 0)
1479  :domain(domain),ghost(g),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1480  {
1481 #ifdef SE_CLASS2
1482  check_new(this,8,GRID_DIST_EVENT,4);
1483 #endif
1484 
1485  if (opt >> 32 != 0)
1486  {this->setDecompositionGranularity(opt >> 32);}
1487 
1488  check_domain(domain);
1492  }
1493 
1494 
1505  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g, const periodicity<dim> & p, size_t opt = 0, const grid_sm<dim,void> & g_dec = grid_sm<dim,void>())
1506  :domain(domain),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1507  {
1508 #ifdef SE_CLASS2
1509  check_new(this,8,GRID_DIST_EVENT,4);
1510 #endif
1511 
1512  if (opt >> 32 != 0)
1513  {this->setDecompositionGranularity(opt >> 32);}
1514 
1515  check_domain(domain);
1517 
1518  ghost = convert_ghost(g,cd_sm);
1519 
1520  InitializeDecomposition(g_sz,p.bc,g_dec);
1521 
1522  // an empty
1524 
1525  // Initialize structures
1526  InitializeStructures(g_sz,empty,g,false);
1527  }
1528 
1529 
1544  grid_dist_id(const size_t (& g_sz)[dim],
1545  const Box<dim,St> & domain,
1546  const Ghost<dim,long int> & g,
1547  const periodicity<dim> & p,
1549  :domain(domain),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz),gint(g)
1550  {
1551 #ifdef SE_CLASS2
1552  check_new(this,8,GRID_DIST_EVENT,4);
1553 #endif
1554 
1557 
1558  ghost = convert_ghost(g,cd_sm);
1559 
1562  this->bx_def = bx_def;
1563  this->use_bx_def = true;
1564  }
1565 
1571  const grid_sm<dim,T> & getGridInfo() const
1572  {
1573 #ifdef SE_CLASS2
1574  check_valid(this,8);
1575 #endif
1576  return ginfo;
1577  }
1578 
1585  {
1586 #ifdef SE_CLASS2
1587  check_valid(this,8);
1588 #endif
1589  return ginfo_v;
1590  }
1591 
1598  {
1599 #ifdef SE_CLASS2
1600  check_valid(this,8);
1601 #endif
1602  return dec;
1603  }
1604 
1611  {
1612 #ifdef SE_CLASS2
1613  check_valid(this,8);
1614 #endif
1615  return dec;
1616  }
1617 
1623  const CellDecomposer_sm<dim,St,shift<dim,St>> & getCellDecomposer() const
1624  {
1625 #ifdef SE_CLASS2
1626  check_valid(this,8);
1627 #endif
1628  return cd_sm;
1629  }
1630 
1638  bool isInside(const grid_key_dx<dim> & gk) const
1639  {
1640 #ifdef SE_CLASS2
1641  check_valid(this,8);
1642 #endif
1643  for (size_t i = 0 ; i < dim ; i++)
1644  {
1645  if (gk.get(i) < 0 || gk.get(i) >= (long int)g_sz[i])
1646  {return false;}
1647  }
1648 
1649  return true;
1650  }
1651 
1657  size_t getLocalDomainSize() const
1658  {
1659 #ifdef SE_CLASS2
1660  check_valid(this,8);
1661 #endif
1662  size_t total = 0;
1663 
1664  for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1665  {
1666  total += gdb_ext.get(i).Dbox.getVolumeKey();
1667  }
1668 
1669  return total;
1670  }
1671 
1678  {
1679 #ifdef SE_CLASS2
1680  check_valid(this,8);
1681 #endif
1682  size_t total = 0;
1683 
1684  for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1685  {
1686  total += gdb_ext.get(i).GDbox.getVolumeKey();
1687  }
1688 
1689  return total;
1690  }
1691 
1692 
1699  {
1700 #ifdef SE_CLASS2
1701  check_valid(this,8);
1702 #endif
1703  return gdb_ext;
1704  }
1705 
1712  {
1713 #ifdef SE_CLASS2
1714  check_valid(this,8);
1715 #endif
1716  gdb_ext_global.clear();
1717 
1719  v_cl.execute();
1720 
1721  size_t size_r;
1722  size_t size = gdb_ext_global.size();
1723 
1724  if (v_cl.getProcessUnitID() == 0)
1725  {
1726  for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1727  v_cl.send(i,0,&size,sizeof(size_t));
1728 
1729  size_r = size;
1730  }
1731  else
1732  v_cl.recv(0,0,&size_r,sizeof(size_t));
1733 
1734  v_cl.execute();
1735 
1736  gdb_ext_global.resize(size_r);
1737 
1738 
1739  if (v_cl.getProcessUnitID() == 0)
1740  {
1741  for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1742  v_cl.send(i,0,gdb_ext_global);
1743  }
1744  else
1745  v_cl.recv(0,0,gdb_ext_global);
1746 
1747  v_cl.execute();
1748  }
1749 
1750 
1757  decltype(device_grid::type_of_subiterator()),
1758  FREE>
1760  {
1761 #ifdef SE_CLASS2
1762  check_valid(this,8);
1763 #endif
1764 
1766  grid_key_dx<dim> one;
1767  one.one();
1768  stop = stop - one;
1769 
1771  decltype(device_grid::type_of_subiterator()),
1772  FREE> it(loc_grid_old,gdb_ext_old,stop);
1773 
1774  return it;
1775  }
1776 
1788  {
1790  return it_dec;
1791  }
1792 
1793 #ifdef __NVCC__
1794 
1799  template<typename lambda_t2>
1800  void setPoints(lambda_t2 f2)
1801  {
1802  auto it = getGridIteratorGPU();
1803 
1804  it.template launch<1>(launch_set_dense<dim>(),f2);
1805  }
1806 
1813  template<typename lambda_t2>
1814  void setPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t2 f2)
1815  {
1816  auto it = getGridIteratorGPU(k1,k2);
1817 
1818  it.template launch<0>(launch_set_dense<dim>(),f2);
1819  }
1820 
1826  template<typename lambda_t1, typename lambda_t2>
1827  void addPoints(lambda_t1 f1, lambda_t2 f2)
1828  {
1829  auto it = getGridIteratorGPU();
1830  it.setGPUInsertBuffer(1);
1831 
1832  it.template launch<1>(launch_insert_sparse(),f1,f2);
1833  }
1834 
1842  template<typename lambda_t1, typename lambda_t2>
1843  void addPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t1 f1, lambda_t2 f2)
1844  {
1845  auto it = getGridIteratorGPU(k1,k2);
1846  it.setGPUInsertBuffer(1);
1847 
1848  it.template launch<1>(launch_insert_sparse(),f1,f2);
1849  }
1850 
1865  getGridIteratorGPU(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop)
1866  {
1868  return it_dec;
1869  }
1870 
1882  getGridIteratorGPU()
1883  {
1885  return it_dec;
1886  }
1887 
1888 #endif
1889 
1901  {
1903  return it_dec;
1904  }
1905 
1917  {
1918  grid_key_dx<dim> start;
1919  grid_key_dx<dim> stop;
1920  for (size_t i = 0; i < dim; i++)
1921  {
1922  start.set_d(i, 0);
1923  stop.set_d(i, g_sz[i] - 1);
1924  }
1925 
1927  return it_dec;
1928  }
1929 
1936  decltype(device_grid::type_of_subiterator()),FREE>
1938  {
1939 #ifdef SE_CLASS2
1940  check_valid(this,8);
1941 #endif
1942 
1944  grid_key_dx<dim> one;
1945  one.one();
1946  stop = stop - one;
1947 
1949  decltype(device_grid::type_of_subiterator()),
1950  FREE> it(loc_grid,gdb_ext,stop);
1951 
1952  return it;
1953  }
1954 
1962  template<unsigned int Np>
1964  decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
1965  FREE,
1967  getDomainIteratorStencil(const grid_key_dx<dim> (& stencil_pnt)[Np]) const
1968  {
1969 #ifdef SE_CLASS2
1970  check_valid(this,8);
1971 #endif
1972 
1974  grid_key_dx<dim> one;
1975  one.one();
1976  stop = stop - one;
1977 
1979  decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
1980  FREE,
1981  stencil_offset_compute<dim,Np>> it(loc_grid,gdb_ext,stop,stencil_pnt);
1982 
1983  return it;
1984  }
1985 
1992  decltype(device_grid::type_of_iterator()),
1993  FIXED>
1995  {
1996 #ifdef SE_CLASS2
1997  check_valid(this,8);
1998 #endif
1999  grid_key_dx<dim> stop;
2000  for (size_t i = 0 ; i < dim ; i++)
2001  {stop.set_d(i,0);}
2002 
2004  decltype(device_grid::type_of_iterator()),
2005  FIXED> it(loc_grid,gdb_ext,stop);
2006 
2007  return it;
2008  }
2009 
2024  const grid_key_dx<dim> & stop) const
2025  {
2026 #ifdef SE_CLASS2
2027  check_valid(this,8);
2028 #endif
2030 
2031  return it;
2032  }
2033 
2046  grid_dist_iterator_sub<dim,device_grid> getSubDomainIterator(const long int (& start)[dim], const long int (& stop)[dim]) const
2047  {
2049 
2050  return it;
2051  }
2052 
2055  {
2056 #ifdef SE_CLASS2
2057  check_delete(this);
2058 #endif
2059  dec.decRef();
2060  }
2061 
2068  {
2069 #ifdef SE_CLASS2
2070  check_valid(this,8);
2071 #endif
2072  return v_cl;
2073  }
2074 
2080  {
2081  for (int i = 0 ; i < loc_grid.size() ; i++)
2082  {
2083  loc_grid.get(i).removeUnusedBuffers();
2084  }
2085  }
2086 
2092  bool is_staggered() const
2093  {
2094  return false;
2095  }
2096 
2107  template <typename bg_key> inline void remove(const grid_dist_key_dx<dim,bg_key> & v1)
2108  {
2109 #ifdef SE_CLASS2
2110  check_valid(this,8);
2111 #endif
2112  return loc_grid.get(v1.getSub()).remove(v1.getKey());
2113  }
2114 
2125  template <typename bg_key> inline void remove_no_flush(const grid_dist_key_dx<dim,bg_key> & v1)
2126  {
2127 #ifdef SE_CLASS2
2128  check_valid(this,8);
2129 #endif
2130  return loc_grid.get(v1.getSub()).remove_no_flush(v1.getKey());
2131  }
2132 
2133 
2134  template<typename ... v_reduce>
2135  void flush(flush_type opt = flush_type::FLUSH_ON_HOST)
2136  {
2137  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2138  {
2139  loc_grid.get(i).template flush<v_reduce ...>(v_cl.getmgpuContext(),opt);
2140  }
2141  }
2142 
2153  inline void flush_remove()
2154  {
2155 #ifdef SE_CLASS2
2156  check_valid(this,8);
2157 #endif
2158  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2159  {loc_grid.get(i).flush_remove();}
2160  }
2161 
2175  template <unsigned int p,typename bg_key>inline auto insert(const grid_dist_key_dx<dim,bg_key> & v1)
2176  -> decltype(loc_grid.get(v1.getSub()).template insert<p>(v1.getKey()))
2177  {
2178 #ifdef SE_CLASS2
2179  check_valid(this,8);
2180 #endif
2181 
2182  return loc_grid.get(v1.getSub()).template insert<p>(v1.getKey());
2183  }
2184 
2185 
2202  template <unsigned int p,typename bg_key>inline auto insertFlush(const grid_dist_key_dx<dim,bg_key> & v1)
2203  -> decltype(loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey()))
2204  {
2205 #ifdef SE_CLASS2
2206  check_valid(this,8);
2207 #endif
2208 
2209  return loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey());
2210  }
2211 
2220  template <unsigned int p, typename bg_key>
2221  inline auto get(const grid_dist_key_dx<dim,bg_key> & v1) const
2222  -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
2223  {
2224 #ifdef SE_CLASS2
2225  check_valid(this,8);
2226 #endif
2227  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2228  }
2229 
2230 
2239  template <unsigned int p, typename bg_key>
2240  inline auto get(const grid_dist_key_dx<dim,bg_key> & v1)
2241  -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2242  {
2243 #ifdef SE_CLASS2
2244  check_valid(this,8);
2245 #endif
2246  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2247  }
2248 
2257  template <unsigned int p = 0>
2258  inline auto get(const grid_dist_g_dx<device_grid> & v1) const
2259  -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2260  {
2261 #ifdef SE_CLASS2
2262  check_valid(this,8);
2263 #endif
2264  return v1.getSub()->template get<p>(v1.getKey());
2265  }
2266 
2275  template <unsigned int p = 0>
2276  inline auto get(const grid_dist_g_dx<device_grid> & v1) -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2277  {
2278 #ifdef SE_CLASS2
2279  check_valid(this,8);
2280 #endif
2281  return v1.getSub()->template get<p>(v1.getKey());
2282  }
2283 
2292  template <unsigned int p = 0>
2293  inline auto get(const grid_dist_lin_dx & v1) const -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2294  {
2295 #ifdef SE_CLASS2
2296  check_valid(this,8);
2297 #endif
2298  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2299  }
2300 
2309  template <unsigned int p = 0>
2310  inline auto get(const grid_dist_lin_dx & v1) -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2311  {
2312 #ifdef SE_CLASS2
2313  check_valid(this,8);
2314 #endif
2315  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2316  }
2317 
2326  template <typename bg_key>
2328  {
2329 #ifdef SE_CLASS2
2330  check_valid(this,8);
2331 #endif
2332  Point<dim,St> p;
2333 
2334  for (int i = 0 ; i < dim ; i++)
2335  {
2336  p.get(i) = (gdb_ext.get(v1.getSub()).origin.get(i) + v1.getKeyRef().get(i)) * this->spacing(i) + domain.getLow(i);
2337  }
2338 
2339  return p;
2340  }
2341 
2349  template<typename bg_key>
2350  inline bool existPoint(const grid_dist_key_dx<dim,bg_key> & v1) const
2351  {
2352  return loc_grid.get(v1.getSub()).existPoint(v1.getKey());
2353  }
2354 
2363  template <unsigned int p = 0, typename bgkey>
2364  inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) const -> decltype(this->template get<p>(v1))
2365  {
2366  return this->template get<p>(v1);
2367  }
2368 
2377  template <unsigned int p = 0, typename bgkey>
2378  inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) -> decltype(this->template get<p>(v1))
2379  {
2380  return this->template get<p>(v1);
2381  }
2382 
2388  template<int... prp> void ghost_get(size_t opt = 0)
2389  {
2390 #ifdef SE_CLASS2
2391  check_valid(this,8);
2392 #endif
2393 
2394  // Convert the ghost internal boxes into grid unit boxes
2395  create_ig_box();
2396 
2397  // Convert the ghost external boxes into grid unit boxes
2398  create_eg_box();
2399 
2400  // Convert the local ghost internal boxes into grid unit boxes
2402 
2403  // Convert the local external ghost boxes into grid unit boxes
2405 
2407  eg_box,
2408  loc_ig_box,
2409  loc_eg_box,
2410  gdb_ext,
2411  eb_gid_list,
2412  use_bx_def,
2413  loc_grid,
2414  ginfo_v,
2416  opt);
2417  }
2418 
2424  template<template<typename,typename> class op,int... prp> void ghost_put()
2425  {
2426 #ifdef SE_CLASS2
2427  check_valid(this,8);
2428 #endif
2429 
2430  // Convert the ghost internal boxes into grid unit boxes
2431  create_ig_box();
2432 
2433  // Convert the ghost external boxes into grid unit boxes
2434  create_eg_box();
2435 
2436  // Convert the local ghost internal boxes into grid unit boxes
2438 
2439  // Convert the local external ghost boxes into grid unit boxes
2441 
2443  ig_box,
2444  eg_box,
2445  loc_ig_box,
2446  loc_eg_box,
2447  gdb_ext,
2448  loc_grid,
2450  }
2451 
2452 
2466  {
2467  if (T::noPointers() == true && use_memcpy)
2468  {
2469  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2470  {
2471  auto & gs_src = this->get_loc_grid(i).getGrid();
2472 
2473  long int start = gs_src.LinId(gdb_ext.get(i).Dbox.getKP1());
2474  long int stop = gs_src.LinId(gdb_ext.get(i).Dbox.getKP2());
2475 
2476  if (stop < start) {continue;}
2477 
2478  void * dst = static_cast<void *>(static_cast<char *>(this->get_loc_grid(i).getPointer()) + start*sizeof(T));
2479  void * src = static_cast<void *>(static_cast<char *>(g.get_loc_grid(i).getPointer()) + start*sizeof(T));
2480 
2481  memcpy(dst,src,sizeof(T) * (stop + 1 - start));
2482  }
2483  }
2484  else
2485  {
2486  grid_key_dx<dim> cnt[1];
2487  cnt[0].zero();
2488 
2489  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2490  {
2491  auto & dst = this->get_loc_grid(i);
2492  auto & src = g.get_loc_grid(i);
2493 
2494  auto it = this->get_loc_grid_iterator_stencil(i,cnt);
2495 
2496  while (it.isNext())
2497  {
2498  // center point
2499  auto Cp = it.template getStencil<0>();
2500 
2501  dst.insert_o(Cp) = src.get_o(Cp);
2502 
2503  ++it;
2504  }
2505  }
2506  }
2507 
2508  return *this;
2509  }
2510 
2524  {
2525  grid_key_dx<dim> cnt[1];
2526  cnt[0].zero();
2527 
2528  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2529  {
2530  auto & dst = this->get_loc_grid(i);
2531  auto & src = g.get_loc_grid(i);
2532 
2533  dst = src;
2534  }
2535  return *this;
2536  }
2537 
2544  {
2545  return cd_sm.getCellBox().getP2();
2546  }
2547 
2559  {
2560 #ifdef SE_CLASS2
2561  check_valid(this,8);
2562 #endif
2563  // Get the sub-domain id
2564  size_t sub_id = k.getSub();
2565 
2566  grid_key_dx<dim> k_glob = k.getKey();
2567 
2568  // shift
2569  k_glob = k_glob + gdb_ext.get(sub_id).origin;
2570 
2571  return k_glob;
2572  }
2573 
2582  template <typename Model>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2583  {
2584  CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2585 
2587  auto & dist = getDecomposition().getDistribution();
2588 
2589  cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2590 
2591  // Invert the id to positional
2592 
2593  Point<dim,St> p;
2594  for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2595  {
2596  dist.getSubSubDomainPos(i,p);
2597  dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1 + md.resolution(p));
2598  }
2599 
2600  dec.computeCommunicationAndMigrationCosts(ts);
2601 
2602  dist.setDistTol(md.distributionTol());
2603  }
2604 
2609  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, unsigned int N, typename lambda_f, typename ... ArgsT >
2610  void conv(int (& stencil)[N][dim], grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2611  {
2612  for (int i = 0 ; i < loc_grid.size() ; i++)
2613  {
2614  Box<dim,long int> inte;
2615 
2616  Box<dim,long int> base;
2617  for (int j = 0 ; j < dim ; j++)
2618  {
2619  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2620  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2621  }
2622 
2623  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2624 
2625  bool overlap = dom.Intersect(base,inte);
2626 
2627  if (overlap == true)
2628  {
2629  loc_grid.get(i).template conv<prop_src,prop_dst,stencil_size>(stencil,inte.getKP1(),inte.getKP2(),func,args...);
2630  }
2631  }
2632  }
2633 
2638  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2639  void conv_cross(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2640  {
2641  for (int i = 0 ; i < loc_grid.size() ; i++)
2642  {
2643  Box<dim,long int> inte;
2644 
2645  Box<dim,long int> base;
2646  for (int j = 0 ; j < dim ; j++)
2647  {
2648  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2649  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2650  }
2651 
2652  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2653 
2654  bool overlap = dom.Intersect(base,inte);
2655 
2656  if (overlap == true)
2657  {
2658  loc_grid.get(i).template conv_cross<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2659  }
2660  }
2661  }
2662 
2667  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2668  void conv_cross_b(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2669  {
2670  for (int i = 0 ; i < loc_grid.size() ; i++)
2671  {
2672  Box<dim,long int> inte;
2673 
2674  Box<dim,long int> base;
2675  for (int j = 0 ; j < dim ; j++)
2676  {
2677  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2678  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2679  }
2680 
2681  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2682 
2683  bool overlap = dom.Intersect(base,inte);
2684 
2685  if (overlap == true)
2686  {
2687  loc_grid.get(i).template conv_cross_b<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2688  }
2689  }
2690  }
2691 
2696  template<unsigned int stencil_size, typename v_type, typename lambda_f, typename ... ArgsT >
2697  void conv_cross_ids(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2698  {
2699  for (int i = 0 ; i < loc_grid.size() ; i++)
2700  {
2701  Box<dim,long int> inte;
2702 
2703  Box<dim,long int> base;
2704  for (int j = 0 ; j < dim ; j++)
2705  {
2706  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2707  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2708  }
2709 
2710  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2711 
2712  bool overlap = dom.Intersect(base,inte);
2713 
2714  if (overlap == true)
2715  {
2716  loc_grid.get(i).template conv_cross_ids<stencil_size,v_type>(inte.getKP1(),inte.getKP2(),func,args...);
2717  }
2718  }
2719  }
2720 
2725  template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_dst1, unsigned int prop_dst2, unsigned int stencil_size, unsigned int N, typename lambda_f, typename ... ArgsT >
2726  void conv2(int (& stencil)[N][dim], grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2727  {
2728  for (int i = 0 ; i < loc_grid.size() ; i++)
2729  {
2730  Box<dim,long int> inte;
2731 
2732  Box<dim,long int> base;
2733  for (int j = 0 ; j < dim ; j++)
2734  {
2735  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2736  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2737  }
2738 
2739  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2740 
2741  bool overlap = dom.Intersect(base,inte);
2742 
2743  if (overlap == true)
2744  {
2745  loc_grid.get(i).template conv2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(stencil,inte.getKP1(),inte.getKP2(),func,create_vcluster().rank(),args...);
2746  }
2747  }
2748  }
2749 
2754  template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_dst1, unsigned int prop_dst2, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2755  void conv2(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2756  {
2757  for (int i = 0 ; i < loc_grid.size() ; i++)
2758  {
2759  Box<dim,long int> inte;
2760 
2761  Box<dim,long int> base;
2762  for (int j = 0 ; j < dim ; j++)
2763  {
2764  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2765  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2766  }
2767 
2768  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2769 
2770  bool overlap = dom.Intersect(base,inte);
2771 
2772  if (overlap == true)
2773  {
2774  loc_grid.get(i).template conv2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2775  }
2776  }
2777  }
2778 
2783  template<unsigned int prop_src1, unsigned int prop_dst1, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2784  void conv(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2785  {
2786  for (int i = 0 ; i < loc_grid.size() ; i++)
2787  {
2788  Box<dim,long int> inte;
2789 
2790  Box<dim,long int> base;
2791  for (int j = 0 ; j < dim ; j++)
2792  {
2793  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2794  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2795  }
2796 
2797  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2798 
2799  bool overlap = dom.Intersect(base,inte);
2800 
2801  if (overlap == true)
2802  {
2803  loc_grid.get(i).template conv<prop_src1,prop_dst1,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2804  }
2805  }
2806  }
2807 
2812  template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_dst1, unsigned int prop_dst2, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2813  void conv2_b(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2814  {
2815  for (int i = 0 ; i < loc_grid.size() ; i++)
2816  {
2817  Box<dim,long int> inte;
2818 
2819  Box<dim,long int> base;
2820  for (int j = 0 ; j < dim ; j++)
2821  {
2822  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2823  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2824  }
2825 
2826  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2827 
2828  bool overlap = dom.Intersect(base,inte);
2829 
2830  if (overlap == true)
2831  {
2832  loc_grid.get(i).template conv2_b<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2833  }
2834  }
2835  }
2836 
2837  template<typename NNtype>
2838  void findNeighbours()
2839  {
2840  for (int i = 0 ; i < loc_grid.size() ; i++)
2841  {
2842  loc_grid.get(i).findNeighbours();
2843  }
2844  }
2845 
2850  template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_dst1, unsigned int prop_dst2, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2851  void conv_cross2(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2852  {
2853  for (int i = 0 ; i < loc_grid.size() ; i++)
2854  {
2855  Box<dim,long int> inte;
2856 
2857  Box<dim,long int> base;
2858  for (int j = 0 ; j < dim ; j++)
2859  {
2860  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2861  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2862  }
2863 
2864  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2865 
2866  bool overlap = dom.Intersect(base,inte);
2867 
2868  if (overlap == true)
2869  {
2870  loc_grid.get(i).template conv_cross2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2871  }
2872  }
2873  }
2874 
2886  bool write(std::string output, size_t opt = VTK_WRITER | FORMAT_BINARY )
2887  {
2888 #ifdef SE_CLASS2
2889  check_valid(this,8);
2890 #endif
2891 
2892  file_type ft = file_type::ASCII;
2893 
2894  if (opt & FORMAT_BINARY)
2895  {ft = file_type::BINARY;}
2896 
2897  // Create a writer and write
2899  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2900  {
2901  Point<dim,St> offset = getOffset(i);
2902 
2903  if (opt & PRINT_GHOST)
2904  {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).GDbox);}
2905  else
2906  {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);}
2907  }
2908  vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk", prp_names, "grids", ft);
2909 
2910  return true;
2911  }
2912 
2918  bool write_debug(std::string output)
2919  {
2920  for (int i = 0 ; i < getN_loc_grid() ; i++)
2921  {
2922  Point<dim,St> sp;
2923  Point<dim,St> offset;
2924 
2925  for (int j = 0 ; j < dim ; j++)
2926  {sp.get(j) = this->spacing(j);}
2927 
2928  offset = gdb_ext.get(i).origin;
2929 
2930  get_loc_grid(i).write_debug(output + "_" + std::to_string(i) + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk",sp,offset);
2931  }
2932 
2933  return true;
2934  }
2935 
2948  bool write_frame(std::string output, size_t i, size_t opt = VTK_WRITER | FORMAT_ASCII)
2949  {
2950 #ifdef SE_CLASS2
2951  check_valid(this,8);
2952 #endif
2953  file_type ft = file_type::ASCII;
2954 
2955  if (opt & FORMAT_BINARY)
2956  ft = file_type::BINARY;
2957 
2958  // Create a writer and write
2960  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2961  {
2962  Point<dim,St> offset = getOffset(i);
2963  vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);
2964  }
2965  vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(i) + ".vtk",prp_names,"grids",ft);
2966 
2967  return true;
2968  }
2969 
2970 
2971 
2980  {
2981  return loc_grid.get(i);
2982  }
2983 
2992  {
2993  return grid_key_dx_iterator_sub<dim,no_stencil>(loc_grid.get(i).getGrid(),
2994  gdb_ext.get(i).Dbox.getKP1(),
2995  gdb_ext.get(i).Dbox.getKP2());
2996  }
2997 
3005  template<unsigned int Np>
3006  grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>
3007  get_loc_grid_iterator_stencil(size_t i,const grid_key_dx<dim> (& stencil_pnt)[Np])
3008  {
3009  return grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>(loc_grid.get(i).getGrid(),
3010  gdb_ext.get(i).Dbox.getKP1(),
3011  gdb_ext.get(i).Dbox.getKP2(),
3012  stencil_pnt);
3013  }
3014 
3020  size_t getN_loc_grid()
3021  {
3022  return loc_grid.size();
3023  }
3024 
3025 
3033  long int who()
3034  {
3035 #ifdef SE_CLASS2
3036  return check_whoami(this,8);
3037 #else
3038  return -1;
3039 #endif
3040  }
3041 
3046  void debugPrint()
3047  {
3048  size_t tot_volume = 0;
3049 
3050  std::cout << "-------- External Ghost boxes ---------- " << std::endl;
3051 
3052  for (size_t i = 0 ; i < eg_box.size() ; i++)
3053  {
3054  std::cout << "Processor: " << eg_box.get(i).prc << " Boxes:" << std::endl;
3055 
3056  for (size_t j = 0; j < eg_box.get(i).bid.size() ; j++)
3057  {
3058  std::cout << " Box: " << eg_box.get(i).bid.get(j).g_e_box.toString() << " Id: " << eg_box.get(i).bid.get(j).g_id << std::endl;
3059  tot_volume += eg_box.get(i).bid.get(j).g_e_box.getVolumeKey();
3060  }
3061  }
3062 
3063  std::cout << "TOT volume external ghost " << tot_volume << std::endl;
3064 
3065  std::cout << "-------- Internal Ghost boxes ---------- " << std::endl;
3066 
3067  tot_volume = 0;
3068  for (size_t i = 0 ; i < ig_box.size() ; i++)
3069  {
3070  std::cout << "Processor: " << ig_box.get(i).prc << " Boxes:" << std::endl;
3071 
3072  for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
3073  {
3074  std::cout << " Box: " << ig_box.get(i).bid.get(j).box.toString() << " Id: " << ig_box.get(i).bid.get(j).g_id << std::endl;
3075  tot_volume += ig_box.get(i).bid.get(j).box.getVolumeKey();
3076  }
3077  }
3078 
3079  std::cout << "TOT volume internal ghost " << tot_volume << std::endl;
3080  }
3081 
3090  {
3091  prp_names = names;
3092  }
3093 
3102  {
3103  return prp_names;
3104  }
3105 
3112  void clear()
3113  {
3114  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3115  {loc_grid.get(i).clear();}
3116  }
3117 
3124  void construct_link(self & grid_up, self & grid_dw)
3125  {
3126  for (int i = 0 ; i < loc_grid.size() ; i++)
3127  {
3128  loc_grid.get(i).construct_link(grid_up.get_loc_grid(i),grid_dw.get_loc_grid(i),v_cl.getmgpuContext());
3129  }
3130  }
3131 
3138  void construct_link_dw(self & grid_dw, openfpm::vector<offset_mv<dim>> & mvof)
3139  {
3140  for (int i = 0 ; i < loc_grid.size() ; i++)
3141  {
3142  Point<dim,int> p_dw;
3143  for(int j = 0 ; j < dim ; j++)
3144  {p_dw.get(j) = mvof.get(i).dw.get(j);}
3145 
3146  loc_grid.get(i).construct_link_dw(grid_dw.get_loc_grid(i),gdb_ext.get(i).Dbox,p_dw,v_cl.getmgpuContext());
3147  }
3148  }
3149 
3156  void construct_link_up(self & grid_up, openfpm::vector<offset_mv<dim>> & mvof)
3157  {
3158  for (int i = 0 ; i < loc_grid.size() ; i++)
3159  {
3160  Point<dim,int> p_up;
3161  for(int j = 0 ; j < dim ; j++)
3162  {p_up.get(j) = mvof.get(i).up.get(j);}
3163 
3164  loc_grid.get(i).construct_link_up(grid_up.get_loc_grid(i),gdb_ext.get(i).Dbox,p_up,v_cl.getmgpuContext());
3165  }
3166  }
3167 
3174  template<typename stencil_type>
3176  {
3177  for (int i = 0 ; i < loc_grid.size() ; i++)
3178  {
3179  // we limit to the domain subset for tagging
3180 
3181  Box_check<dim,unsigned int> chk(gdb_ext.get(i).Dbox);
3182 
3183 
3184  loc_grid.get(i).template tagBoundaries<stencil_type>(v_cl.getmgpuContext(),chk);
3185  }
3186  }
3187 
3191  void map(size_t opt = 0)
3192  {
3193  // Save the background values
3194  T bv;
3195 
3196  copy_aggregate_dual<decltype(loc_grid.get(0).getBackgroundValue()),
3197  T> ca(loc_grid.get(0).getBackgroundValue(),bv);
3198 
3199  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(ca);
3200 
3201  if (!(opt & NO_GDB_EXT_SWITCH))
3202  {
3203  gdb_ext_old = gdb_ext;
3205 
3207  }
3208 
3210 
3212 
3213  loc_grid_old.clear();
3214  loc_grid_old.shrink_to_fit();
3215  gdb_ext_old.clear();
3216 
3217  // reset ghost structure to recalculate
3218  reset_ghost_structures();
3219 
3220  // Reset the background values
3221  setBackgroundValue(bv);
3222  }
3223 
3229  inline void save(const std::string & filename) const
3230  {
3232 
3233  h5s.save(filename,loc_grid,gdb_ext);
3234  }
3235 
3241  inline void load(const std::string & filename)
3242  {
3244 
3245  h5l.load<device_grid>(filename,loc_grid_old,gdb_ext_old);
3246 
3247  if (v_cl.size() != 1)
3248  {
3249  // Map the distributed grid
3250  map(NO_GDB_EXT_SWITCH);
3251  }
3252  else
3253  {
3254  for (int i = 0 ; i < gdb_ext_old.size() ; i++)
3255  {
3256  auto & lg = loc_grid_old.get(i);
3257  auto it_src = lg.getIterator(gdb_ext_old.get(i).Dbox.getKP1(),gdb_ext_old.get(i).Dbox.getKP2());
3258  auto & dg = loc_grid.get(0);
3259  grid_key_dx<dim> kp1 = gdb_ext.get(0).Dbox.getKP1();
3260 
3261  grid_key_dx<dim> orig;
3262  for (int j = 0 ; j < dim ; j++)
3263  {
3264  orig.set_d(j,gdb_ext_old.get(i).origin.get(j));
3265  }
3266 
3267  while (it_src.isNext())
3268  {
3269  auto key = it_src.get();
3270  grid_key_dx<dim> key_dst;
3271 
3272  for (int j = 0 ; j < dim ; j++)
3273  {key_dst.set_d(j,key.get(j) + orig.get(j) + kp1.get(j));}
3274 
3275  dg.insert_o(key_dst) = lg.get_o(key);
3276 
3277  ++it_src;
3278  }
3279  }
3280  }
3281  }
3282 
3288  template <typename stencil = no_stencil>
3290  {
3292  }
3293 
3300  {
3301  return this->loc_ig_box;
3302  }
3303 
3310  {
3311  return this->ig_box;
3312  }
3313 
3314  void print_stats()
3315  {
3316  std::cout << "-- REPORT --" << std::endl;
3317 #ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3318  std::cout << "Processor: " << v_cl.rank() << " Time spent in packing data: " << tot_pack << std::endl;
3319  std::cout << "Processor: " << v_cl.rank() << " Time spent in sending and receving data: " << tot_sendrecv << std::endl;
3320  std::cout << "Processor: " << v_cl.rank() << " Time spent in merging: " << tot_merge << std::endl;
3321  std::cout << "Processor: " << v_cl.rank() << " Time spent in local merging: " << tot_loc_merge << std::endl;
3322 #else
3323 
3324  std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3325 
3326 #endif
3327  }
3328 
3329  void clear_stats()
3330  {
3331 #ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3332  tot_pack = 0;
3333  tot_sendrecv = 0;
3334  tot_merge = 0;
3335 #else
3336 
3337  std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3338 
3339 #endif
3340  }
3341 
3342 #ifdef __NVCC__
3343 
3349  void setNumberOfInsertPerThread(size_t n_ins)
3350  {
3351  gpu_n_insert_thread = n_ins;
3352  }
3353 
3354  template<typename func_t,typename it_t, typename ... args_t>
3355  void iterateGridGPU(it_t & it, args_t ... args)
3356  {
3357  // setGPUInsertBuffer must be called in anycase even with 0 points to insert
3358  // the loop "it.isNextGrid()" does not guarantee to call it for all local grids
3359  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3360  {loc_grid.get(i).setGPUInsertBuffer(0ul,1ul);}
3361 
3362  while(it.isNextGrid())
3363  {
3364  Box<dim,size_t> b = it.getGridBox();
3365 
3366  size_t i = it.getGridId();
3367 
3368  auto ite = loc_grid.get(i).getGridGPUIterator(b.getKP1int(),b.getKP2int());
3369 
3370  loc_grid.get(i).setGPUInsertBuffer(ite.nblocks(),ite.nthrs());
3371  loc_grid.get(i).initializeGPUInsertBuffer();
3372 
3373  ite_gpu_dist<dim> itd = ite;
3374 
3375  for (int j = 0 ; j < dim ; j++)
3376  {
3377  itd.origin.set_d(j,gdb_ext.get(i).origin.get(j));
3378  itd.start_base.set_d(j,0);
3379  }
3380 
3381  CUDA_LAUNCH((grid_apply_functor),ite,loc_grid.get(i).toKernel(),itd,func_t(),args...);
3382 
3383  it.nextGrid();
3384  }
3385  }
3386 
3392  void removePoints(Box<dim,size_t> & box)
3393  {
3394  Box<dim,long int> box_i = box;
3395 
3396  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3397  {
3398  Box<dim,long int> bx = gdb_ext.get(i).Dbox + gdb_ext.get(i).origin;
3399 
3400  Box<dim,long int> bout;
3401  bool inte = bx.Intersect(box,bout);
3402  bout -= gdb_ext.get(i).origin;
3403 
3404  if (inte == true)
3405  {
3406  loc_grid.get(i).copyRemoveReset();
3407  loc_grid.get(i).remove(bout);
3408  loc_grid.get(i).removePoints(v_cl.getmgpuContext());
3409  }
3410  }
3411  }
3412 
3416  template<unsigned int ... prp> void deviceToHost()
3417  {
3418  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3419  {
3420  loc_grid.get(i).template deviceToHost<prp ...>();
3421  }
3422  }
3423 
3427  template<unsigned int ... prp> void hostToDevice()
3428  {
3429  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3430  {
3431  loc_grid.get(i).template hostToDevice<prp ...>();
3432  }
3433  }
3434 
3435 #endif
3436 
3437 
3439  //\cond
3441  //\endcond
3442 };
3443 
3444 
3445 template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St> >
3447 
3448 template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3450 
3451 template<unsigned int dim, typename St, typename T, typename devg, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3453 
3454 #ifdef __NVCC__
3455 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3457 
3458 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3460 
3461 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3463 #endif
3464 
3465 #endif
bool init_e_g_box
Flag that indicate if the external ghost box has been initialized.
size_t g_id
Global id of the internal ghost box.
std::unordered_map< size_t, size_t > g_id_to_external_ghost_box
auto insertFlush(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).template insertFlush< p >(v1.getKey()))
insert an element in the grid
Decomposition decomposition
Decomposition used.
openfpm::vector< size_t > recv_sz
Receiving size.
size_t g_sz[dim]
Size of the grid on each dimension.
Vcluster & v_cl
Communicator class.
openfpm::vector< Box< dim, long int > > bx_def
Set of boxes that define where the grid is defined.
void magnify_fix_P1(T mg)
Magnify the box by a factor keeping fix the point P1.
Definition: Box.hpp:907
openfpm::vector< e_lbox_grid< dim > > loc_eg_box
Local external ghost boxes in grid units.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
grid_key_dx_iterator_sub< dim, stencil_offset_compute< dim, Np >, typename device_grid::linearizer_type > get_loc_grid_iterator_stencil(size_t i, const grid_key_dx< dim >(&stencil_pnt)[Np])
Get the i sub-domain grid.
void conv2_b(grid_key_dx< dim > start, grid_key_dx< dim > stop, lambda_f func, ArgsT ... args)
apply a convolution on 2 property on GPU
bool write(std::string output, size_t opt=VTK_WRITER|FORMAT_BINARY)
Write the distributed grid information.
comb< dim > cmb
In which sector live the box.
bool use_bx_def
Indicate if we have to use bx_def to define the grid.
Point< dim, St > getSpacing()
Get the spacing on each dimension.
base_key & getKeyRef()
Get the reference key.
void construct_link_dw(self &grid_dw, openfpm::vector< offset_mv< dim >> &mvof)
construct link between current and the level down
Point< dim, long int > dw
offset to move on the lower grid (finer)
bool is_staggered() const
Indicate that this grid is not staggered.
void getGlobalGridsInfo(openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_global) const
It gathers the information about local grids for all of the processors.
comb< dim > cmb
Sector position of the external ghost.
grid_dist_id(const Decomposition &dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
size_t getProcessUnitID()
Get the process unit id.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext
Extension of each grid: Domain and ghost + domain.
const openfpm::vector< i_lbox_grid< dim > > & get_ig_box()
Get the internal ghost box.
Decomposition dec
Space Decomposition.
grid_dist_id_iterator_dec< Decomposition, true > getGridGhostIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
bool write_frame(std::string output, size_t i, size_t opt=VTK_WRITER|FORMAT_ASCII)
Write the distributed grid information.
static const unsigned int dims
Number of dimensions.
This class is an helper for the communication of grid_dist_id.
auto get(const grid_dist_lin_dx &v1) const -> decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))
Get the reference of the selected element.
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition using a resolution function.
Distributed linearized key.
Ghost< dim, St > ghost
Ghost expansion.
void ghost_put_(Decomposition &dec, const openfpm::vector< ip_box_grid< dim >> &ig_box, const openfpm::vector< ep_box_grid< dim >> &eg_box, const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< device_grid > &loc_grid, openfpm::vector< std::unordered_map< size_t, size_t >> &g_id_to_internal_ghost_box)
It merge the information in the ghost with the real information.
void remove(const grid_dist_key_dx< dim, bg_key > &v1)
remove an element in the grid
size_t size() const
Return the total number of points in the grid.
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:637
size_t sub
sub_id in which sub-domain this box live
const openfpm::vector< i_lbox_grid< dim > > & get_loc_ig_box()
Get the internal local ghost box.
bool init_local_i_g_box
Indicate if the local internal ghost box has been initialized.
void construct_link(self &grid_up, self &grid_dw)
construct link between levels
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
void removeUnusedBuffers()
Eliminate many internal temporary buffer you can use this between flushes if you get some out of memo...
openfpm::vector< device_grid > loc_grid_old
Old local grids.
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &k) const
Convert a g_dist_key_dx into a global key.
grid_dist_id(const grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g)
Copy constructor.
size_t opt
Receiving option.
grid_sm< dim, T > ginfo
Grid informations object.
void set_for_adjustment(size_t sub_id, const Box< dim, St > &sub_domain_other, const comb< dim > &cmb, Box< dim, long int > &ib, Ghost< dim, long int > &g)
this function is for optimization of the ghost size
grid_dist_id(const grid_dist_id< dim, St, H, typename Decomposition::base_type, Memory, grid_cpu< dim, H >> &g, const Ghost< dim, long int > &gh, Box< dim, size_t > ext)
This constructor is special, it construct an expanded grid that perfectly overlap with the previous.
base_key getKey() const
Get the key.
size_t gpu_n_insert_thread
number of insert each GPU thread does
const grid_sm< dim, void > & getGridInfoVoid() const
Get an object containing the grid informations without type.
void create_eg_box()
Create per-processor internal ghost box list in grid units.
T value_type
value_type
device_grid device_grid_type
Type of device grid.
void create_local_eg_box()
Create per-processor external ghost boxes list in grid units.
void conv_cross2(grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
size_t g_id
id
Box< dim, size_t > bx
Box in global unit.
void sign_flip()
Flip the sign of the combination.
Definition: comb.hpp:124
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_global
Global gdb_ext.
auto get(const grid_dist_key_dx< dim, bg_key > &v1) const -> typename std::add_lvalue_reference< decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))>::type
Get the reference of the selected element.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
auto get(const grid_dist_g_dx< device_grid > &v1) -> decltype(v1.getSub() ->template get< p >(v1.getKey()))
Get the reference of the selected element.
size_t sub
sub
Grid key for a distributed grid.
void check_size(const size_t(&g_sz)[dim])
Check the grid has a valid size.
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, long int > &g, const periodicity< dim > &p, openfpm::vector< Box< dim, long int >> &bx_def)
It construct a grid on the full domain restricted to the set of boxes specified.
Point< dim, St > getPos(const grid_dist_key_dx< dim, bg_key > &v1)
Get the reference of the selected element.
size_t size()
Stub size.
Definition: map_vector.hpp:211
::Box< dim, long int > box
Box.
auto insert(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).template insert< p >(v1.getKey()))
insert an element in the grid
St spacing(size_t i) const
Get the spacing of the grid in direction i.
const CellDecomposer_sm< dim, St, shift< dim, St > > & getCellDecomposer() const
Return the cell decomposer.
size_t getLocalDomainWithGhostSize() const
Get the total number of grid points with ghost for the calling processor.
comb< dim > cmb
Sector where it live the linked external ghost box.
bool send(size_t proc, size_t tag, const void *mem, size_t sz)
Send data to a processor.
void conv_cross(grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
openfpm::vector< i_lbox_grid< dim > > loc_ig_box
Local internal ghost boxes in grid units.
void Create(openfpm::vector< Box< dim, long int >> &bx_def, const Ghost< dim, long int > &g, bool use_bx_def)
Create the grids on memory.
This class allocate, and destroy CPU memory.
Definition: HeapMemory.hpp:39
void InitializeStructures(const size_t(&g_sz)[dim], openfpm::vector< Box< dim, long int >> &bx, const Ghost< dim, long int > &g, bool use_bx_def)
Initialize the grid.
Internal ghost box sent to construct external ghost box into the other processors.
Structure for stencil iterator.
void one()
Set to one the key.
Definition: grid_key.hpp:179
size_t g_id
Id.
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, long int > &g, const periodicity< dim > &p, size_t opt=0, const grid_sm< dim, void > &g_dec=grid_sm< dim, void >())
Implementation of VCluster class.
Definition: VCluster.hpp:58
auto getProp(const grid_dist_key_dx< dim, bgkey > &v1) const -> decltype(this->template get< p >(v1))
Get the reference of the selected element.
void conv(int(&stencil)[N][dim], grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
Point< dim, long int > up
offset to move up on an upper grid (coarse)
This structure store the Box that define the domain inside the Ghost + domain box.
Definition: GBoxes.hpp:39
void InitializeStructures(const size_t(&g_sz)[dim])
Initialize the grid.
void execute()
Execute all the requests.
This class define the domain decomposition interface.
bool write_debug(std::string output)
Write all grids indigually.
void setBackgroundValue(T &bv)
set the background value
bool init_i_g_box
Flag that indicate if the internal ghost box has been initialized.
grid_key_dx< dim > getKP2() const
Get the point p12 as grid_key_dx.
Definition: Box.hpp:669
device_grid d_grid
Which kind of grid the structure store.
bool init_local_e_g_box
Indicate if the local external ghost box has been initialized.
void InitializeCellDecomposer(const size_t(&g_sz)[dim], const size_t(&bc)[dim])
Initialize the Cell decomposer of the grid.
~grid_dist_id()
Destructor.
void save(const std::string &filename) const
Save the grid state on HDF5.
size_t size(size_t i) const
Return the total number of points in the grid.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_iterator()), FIXED > getDomainGhostIterator() const
It return an iterator that span the grid domain + ghost part.
grid_dist_iterator_sub< dim, device_grid > getSubDomainIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop) const
It return an iterator that span the grid domain only in the specified part.
const openfpm::vector< std::string > & getPropNames()
Set the properties names.
Given the decomposition it create an iterator.
grid_dist_id(const Decomposition2 &dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
void conv_cross_b(grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
grid_dist_iterator< dim, device_grid, decltype(device_grid::template type_of_subiterator< stencil_offset_compute< dim, Np >>()), FREE, stencil_offset_compute< dim, Np > > getDomainIteratorStencil(const grid_key_dx< dim >(&stencil_pnt)[Np]) const
It return an iterator that span the full grid domain (each processor span its local domain)
St stype
Type of space.
bool SGather(T &send, S &recv, size_t root)
Semantic Gather, gather the data from all processors into one node.
Definition: VCluster.hpp:450
grid_dist_iterator_sub< dim, device_grid > getSubDomainIterator(const long int(&start)[dim], const long int(&stop)[dim]) const
It return an iterator that span the grid domain only in the specified part.
This class decompose a space into sub-sub-domains and distribute them across processors.
This is a distributed grid.
static Ghost< dim, St > convert_ghost(const Ghost< dim, long int > &gd, const CellDecomposer_sm< dim, St, shift< dim, St >> &cd_sm)
Convert a ghost from grid point units into continus space.
bool existPoint(const grid_dist_key_dx< dim, bg_key > &v1) const
Check if the point exist.
size_t getN_loc_grid()
Return the number of local grid.
CellDecomposer_sm< dim, St, shift< dim, St > > cd_sm
Structure that divide the space into cells.
grid_dist_id_iterator_dec< Decomposition > getGridIterator()
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
It contain the offset necessary to move to coarser and finer level grids.
Box< dim, size_t > getDomain(size_t i)
Given a local sub-domain i with a local grid Domain + ghost return the part of the local grid that is...
grid_sm< dim, void > ginfo_v
Grid informations object without type.
void flush_remove()
remove an element in the grid
it store a box, its unique id and the sub-domain from where it come from
void conv(grid_key_dx< dim > start, grid_key_dx< dim > stop, lambda_f func, ArgsT ... args)
apply a convolution on GPU
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
void zero()
Set p1 and p2 to 0.
Definition: Box.hpp:970
size_t rank()
Get the process unit id.
const openfpm::vector< GBoxes< device_grid::dims > > & getLocalGridsInfo()
It return the informations about the local grids.
static grid_dist_iterator_sub< dim, device_grid > type_of_subiterator()
This is a meta-function return which type of sub iterator a grid produce.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
void clear()
It delete all the points.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:823
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:740
grid_dist_id(Decomposition &&dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
openfpm::vector< e_box_multi< dim > > eb_gid_list
static void * msg_alloc_external_box(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, void *ptr)
Call-back to allocate buffer to receive incoming objects (external ghost boxes)
openfpm::vector< ip_box_grid< dim > > ig_box
Internal ghost boxes in grid units.
void conv2(grid_key_dx< dim > start, grid_key_dx< dim > stop, lambda_f func, ArgsT ... args)
apply a convolution on 2 property on GPU
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
bool recv(size_t proc, size_t tag, void *v, size_t sz)
Recv data from a processor.
void ghost_put()
It synchronize the ghost parts.
Distributed grid iterator.
size_t getProcessingUnits()
Get the total number of processors.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
auto get(const grid_dist_lin_dx &v1) -> decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))
Get the reference of the selected element.
It store the information about the external ghost box.
Ghost< dim, long int > ghost_int
Ghost expansion.
device_grid & get_loc_grid(size_t i)
Get the i sub-domain grid.
grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > & copy_sparse(grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g, bool use_memcpy=true)
Copy the give grid into this grid.
Box< dim, St > domain
Domain.
void conv_cross_ids(grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, St > &g, size_t opt=0)
bool init_fix_ie_g_box
Flag that indicate if the internal and external ghost box has been fixed.
mgpu::ofp_context_t & getmgpuContext(bool iw=true)
If nvidia cuda is activated return a mgpu context.
const Box< dim, St > getDomain() const
Get the domain where the grid is defined.
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, long int > &g, size_t opt=0)
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:1180
Memory memory_type
Type of Memory.
void InitializeCellDecomposer(const CellDecomposer_sm< dim, St, shift< dim, St >> &cd_old, const Box< dim, size_t > &ext)
Initialize the Cell decomposer of the grid enforcing perfect overlap of the cells.
void construct_link_up(self &grid_up, openfpm::vector< offset_mv< dim >> &mvof)
construct link between current and the level up
grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > & copy(grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g, bool use_memcpy=true)
Copy the give grid into this grid.
auto get(const grid_dist_g_dx< device_grid > &v1) const -> decltype(v1.getSub() ->template get< p >(v1.getKey()))
Get the reference of the selected element.
::Box< dim, long int > l_e_box
Box defining the external ghost box in local coordinates for gdb_ext.
void setBackgroundValue(const typename boost::mpl::at< typename T::type, boost::mpl::int_< p >>::type &bv)
set the background value
size_t getLocalDomainSize() const
Get the total number of grid points for the calling processor.
::Box< dim, long int > g_e_box
Box defining the external ghost box in global coordinates.
void remove_no_flush(const grid_dist_key_dx< dim, bg_key > &v1)
remove an element in the grid
void map_(Decomposition &dec, CellDecomposer_sm< dim, St, shift< dim, St >> &cd_sm, openfpm::vector< device_grid > &loc_grid, openfpm::vector< device_grid > &loc_grid_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_old, openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_global)
Moves all the grids that does not belong to the local processor to the respective processor.
openfpm::vector< std::string > prp_names
properties names
size_t getSub() const
Get the local grid.
const Decomposition & getDecomposition() const
Get the object that store the information about the decomposition.
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:95
Declaration grid_key_dx_iterator_sub.
Definition: grid_sm.hpp:156
size_t r_sub
r_sub id of the sub-domain in the sent list
const grid_sm< dim, T > & getGridInfo() const
Get an object containing the grid informations.
auto get(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))
Get the reference of the selected element.
openfpm::vector< HeapMemory > recv_mem_gg
Receiving buffer for particles ghost get.
this class is a functor for "for_each" algorithm
Definition: grid_common.hpp:22
grid_key_dx_iterator_sub< dim, no_stencil > get_loc_grid_iterator(size_t i)
Get the i sub-domain grid.
size_t size_local_inserted() const
Return the local total number of points inserted in the grid.
size_t v_sub_unit_factor
Number of sub-sub-domain for each processor.
size_t size()
Get the total number of processors.
grid_key_dx< dim > getKP1() const
Get the point p1 as grid_key_dx.
Definition: Box.hpp:656
void conv2(int(&stencil)[N][dim], grid_key_dx< dim > start, grid_key_dx< dim > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
void debugPrint()
It print the internal ghost boxes and external ghost boxes in global unit.
void ghost_get(size_t opt=0)
It synchronize the ghost parts.
auto getProp(const grid_dist_key_dx< dim, bgkey > &v1) -> decltype(this->template get< p >(v1))
Get the reference of the selected element.
openfpm::vector< size_t > gdb_ext_markers
void create_ig_box()
Create per-processor internal ghost boxes list in grid units and g_id_to_external_ghost_box.
Structure to copy aggregates.
grid_dist_id(Decomposition &&dec, const size_t(&g_sz)[dim], const Ghost< dim, St > &ghost)
void ghost_get_(const openfpm::vector< ip_box_grid< dim >> &ig_box, const openfpm::vector< ep_box_grid< dim >> &eg_box, const openfpm::vector< i_lbox_grid< dim >> &loc_ig_box, const openfpm::vector< e_lbox_grid< dim >> &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext, const openfpm::vector< e_box_multi< dim >> &eb_gid_list, bool use_bx_def, openfpm::vector< device_grid > &loc_grid, const grid_sm< dim, void > &ginfo, std::unordered_map< size_t, size_t > &g_id_to_external_ghost_box, size_t opt)
It fill the ghost part of the grids.
void check_domain(const Box< dim, St > &dom)
Check the domain is valid.
Distributed grid iterator.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, St > &g, const periodicity< dim > &p, size_t opt=0)
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getOldDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
openfpm::vector< ep_box_grid< dim > > eg_box
External ghost boxes in grid units.
void create_local_ig_box()
Create local internal ghost box in grid units.
openfpm::vector< device_grid > loc_grid
Local grids.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
size_t r_sub
from which sub-domain this internal ghost box is generated (or with which sub-domain is overlapping)
openfpm::vector< std::unordered_map< size_t, size_t > > g_id_to_internal_ghost_box
grid_dist_id(const Decomposition2 &dec, const size_t(&g_sz)[dim], const Ghost< dim, St > &ghost)
void load(const std::string &filename)
Reload the grid from HDF5 file.
bool isInvalidGhost()
check if the Ghost is valid
Definition: Ghost.hpp:106
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:708
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:326
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
bool SSendRecv(openfpm::vector< T > &send, S &recv, openfpm::vector< size_t > &prc_send, openfpm::vector< size_t > &prc_recv, openfpm::vector< size_t > &sz_recv, size_t opt=NONE)
Semantic Send and receive, send the data to processors and receive from the other processors.
Definition: VCluster.hpp:797
Boundary conditions.
Definition: common.hpp:21
Box< dim, long int > GDbox
Ghost + Domain ghost.
Definition: GBoxes.hpp:42
void tagBoundaries()
construct link between current and the level up
long int who()
It return the id of structure in the allocation list.
char c[dim]
Array that store the combination.
Definition: comb.hpp:37
void InitializeDecomposition(const size_t(&g_sz)[dim], const size_t(&bc)[dim], const grid_sm< dim, void > &g_dist=grid_sm< dim, void >())
Initialize the grid.
Point< dim, St > getOffset(size_t i)
Get the point where it start the origin of the grid of the sub-domain i.
Vcluster & getVC()
Get the Virtual Cluster machine.
bool isInside(const grid_key_dx< dim > &gk) const
Check that the global grid key is inside the grid domain.
Distributed linearized key.
void map(size_t opt=0)
It move all the grid parts that do not belong to the local processor to the respective processor.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_old
Extension of each old grid (old): Domain and ghost + domain.