OpenFPM  5.2.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/Ghost.hpp"
9 #include "Space/Shape/Box.hpp"
10 #include "util/mathutil.hpp"
11 #include "VTKWriter/VTKWriter.hpp"
12 #ifdef __NVCC__
13 #include "SparseGridGpu/SparseGridGpu.hpp"
14 #endif
15 #include "Iterators/grid_dist_id_iterator_dec.hpp"
16 #include "Iterators/grid_dist_id_iterator.hpp"
17 #include "Iterators/grid_dist_id_iterator_sub.hpp"
18 #include "grid_dist_key.hpp"
19 #include "NN/CellList/CellDecomposer.hpp"
20 #include "util/object_util.hpp"
21 #include "memory/ExtPreAlloc.hpp"
22 #include "Packer_Unpacker/Packer.hpp"
23 #include "Packer_Unpacker/Unpacker.hpp"
24 #include "Decomposition/CartDecomposition.hpp"
25 #include "data_type/aggregate.hpp"
26 #include "hdf5.h"
27 #include "grid_dist_id_comm.hpp"
28 #include "HDF5_wr/HDF5_wr.hpp"
29 #include "SparseGrid/SparseGrid.hpp"
30 #include "lib/pdata.hpp"
31 #ifdef __NVCC__
32 #include "cuda/grid_dist_id_kernels.cuh"
33 #include "Grid/cuda/grid_dist_id_iterator_gpu.cuh"
34 #endif
35 
39 template<unsigned int dim>
40 struct offset_mv
41 {
44 
47 };
48 
50 template<unsigned int dim>
51 struct Box_fix
52 {
58  size_t g_id;
60  size_t r_sub;
61 };
62 
63 #define NO_GDB_EXT_SWITCH 0x1000
64 
65 template<bool is_sparse>
67 {
68  template<typename key_type1, typename key_type2, typename spg_type, typename lg_type>
69  static void assign(key_type1 & key, key_type2 & key_dst, spg_type & dg, lg_type & lg)
70  {
71  dg.insert_o(key_dst) = lg.get_o(key);
72  }
73 
74  template<typename gdb_ext_type, typename loc_grid_type>
75  static void pre_load(gdb_ext_type & gdb_ext_old, loc_grid_type & loc_grid_old, gdb_ext_type & gdb_ext, loc_grid_type & loc_grid)
76  {
77  }
78 };
79 
80 template<typename e_src, typename e_dst, typename indexT>
82 {
84  const e_src & block_data_src;
85  e_dst & block_data_dst;
86 
87  indexT local_id;
88 
95  __device__ __host__ inline copy_all_prop_sparse(const e_src & block_data_src, e_dst & block_data_dst, indexT local_id)
96  :block_data_src(block_data_src),block_data_dst(block_data_dst),local_id(local_id)
97  {
98  };
99 
100  template<typename T>
101  __device__ __host__ inline void operator()(T& t) const
102  {
103  block_data_dst.template get<T::value>()[local_id] = block_data_src.template get<T::value>();
104  }
105 };
106 
107 template<typename T>
109 {};
110 
111 template<int ... prp>
113 {
114  template<typename this_type, typename dec_type, typename cd_sm_type, typename loc_grid_type, typename gdb_ext_type>
115  static void call(this_type * this_,
116  dec_type & dec,
117  cd_sm_type & cd_sm,
118  loc_grid_type & loc_grid,
119  loc_grid_type & loc_grid_old,
120  gdb_ext_type & gdb_ext,
121  gdb_ext_type & gdb_ext_old,
122  gdb_ext_type & gdb_ext_global,
123  size_t opt)
124  {
125  this_->template map_<prp ...>(dec,cd_sm,loc_grid,loc_grid_old,gdb_ext,gdb_ext_old,gdb_ext_global,opt);
126  }
127 };
128 
129 struct ids_pl
130 {
131  size_t id;
132 
133  bool operator<(const ids_pl & i) const
134  {
135  return id < i.id;
136  }
137 
138  bool operator==(const ids_pl & i) const
139  {
140  return id == i.id;
141  }
142 };
143 
144 template<>
145 struct device_grid_copy<true>
146 {
147  template<typename key_type1, typename key_type2, typename spg_type, typename lg_type>
148  static void assign(key_type1 & key, key_type2 & key_dst, spg_type & dg, lg_type & lg)
149  {
150  typename spg_type::indexT_ local_id;
151  auto block_data_dst = dg.insertBlockFlush(key_dst, local_id);
152  auto block_data_src = lg.get_o(key);
153 
154  copy_all_prop_sparse<decltype(block_data_src),decltype(block_data_dst),decltype(local_id)> cp(block_data_src, block_data_dst, local_id);
155 
156  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,decltype(block_data_dst)::max_prop> >(cp);
157  }
158 
159 
160 
161  template<typename gdb_ext_type, typename loc_grid_type>
162  static void pre_load(gdb_ext_type & gdb_ext_old, loc_grid_type & loc_grid_old, gdb_ext_type & gdb_ext, loc_grid_type & loc_grid)
163  {
164  auto & dg = loc_grid.get(0);
165  auto dlin = dg.getGrid();
166  typedef typename std::remove_reference<decltype(dg)>::type sparse_grid_type;
167 
170 
171  size_t sz[sparse_grid_type::dims];
172 
173  for (int i = 0 ; i < sparse_grid_type::dims ; i++)
174  {sz[i] = 2;}
175 
177 
179  while(it.isNext())
180  {
181  auto key = it.get();
182 
184  for (int i = 0 ; i < sparse_grid_type::dims ; i++)
185  {
186  k.set_d(i,key.get(i)*dlin.getBlockEgdeSize());
187  }
188 
189  gg.add(k);
190  ++it;
191  }
192 
193 
194  for (int i = 0 ; i < gdb_ext_old.size() ; i++)
195  {
196 
197  auto & lg = loc_grid_old.get(i);
198  auto & indexBuffer = lg.private_get_index_array();
199  auto & dg = loc_grid.get(0);
200 
201  auto slin = loc_grid_old.get(i).getGrid();
202 
203  grid_key_dx<sparse_grid_type::dims> kp1 = gdb_ext.get(0).Dbox.getKP1();
204 
206  for (int j = 0 ; j < sparse_grid_type::dims ; j++)
207  {
208  orig.set_d(j,gdb_ext_old.get(i).origin.get(j));
209  }
210 
211  for (int i = 0; i < indexBuffer.size() ; i++)
212  {
213  for (int ex = 0; ex < gg.size() ; ex++) {
214  auto key = slin.InvLinId(indexBuffer.template get<0>(i),0);
216 
217  for (int j = 0 ; j < sparse_grid_type::dims ; j++)
218  {key_dst.set_d(j,key.get(j) + orig.get(j) + kp1.get(j) + gg.get(ex).get(j));}
219 
220  typename sparse_grid_type::indexT_ bid;
221  int lid;
222 
223  dlin.LinId(key_dst,bid,lid);
224 
225  ids.add();
226  ids.last().id = bid;
227  }
228  }
229  }
230 
231  ids.sort();
232  ids.unique();
233 
234  auto & indexBuffer = dg.private_get_index_array();
235  auto & dataBuffer = dg.private_get_data_array();
236  indexBuffer.reserve(ids.size()+8);
237  dataBuffer.reserve(ids.size()+8);
238  for (int i = 0 ; i < ids.size() ; i++)
239  {
240  auto & dg = loc_grid.get(0);
241  dg.insertBlockFlush(ids.get(i).id);
242  }
243  }
244 };
245 
272 template<unsigned int dim,
273  typename St,
274  typename T,
276  typename Memory=HeapMemory ,
277  typename device_grid=grid_cpu<dim,T> >
278 class grid_dist_id : public grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>
279 {
281 
284 
287 
290 
293 
296 
299 
310 
313 
316 
319 
321  size_t g_sz[dim];
322 
324  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
325 
328 
331 
334 
337  std::unordered_map<size_t,size_t> g_id_to_external_ghost_box;
338 
408 
412 
415 
418 
421 
424 
427 
429  bool use_bx_def = false;
430 
432  bool init_local_i_g_box = false;
433 
435  bool init_local_e_g_box = false;
436 
438  bool init_e_g_box = false;
439 
441  bool init_i_g_box = false;
442 
444  bool init_fix_ie_g_box = false;
445 
448 
451 
454 
457 
459  size_t v_sub_unit_factor = 64;
460 
472  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)
473  {
475 
476  g->recv_sz.resize(g->dec.getNNProcessors());
477  g->recv_mem_gg.resize(g->dec.getNNProcessors());
478 
479  // Get the local processor id
480  size_t lc_id = g->dec.ProctoID(i);
481 
482  // resize the receive buffer
483  g->recv_mem_gg.get(lc_id).resize(msg_i);
484  g->recv_sz.get(lc_id) = msg_i;
485 
486  return g->recv_mem_gg.get(lc_id).getPointer();
487  }
488 
501  void set_for_adjustment(size_t sub_id,
502  const Box<dim,St> & sub_domain_other,
503  const comb<dim> & cmb,
504  Box<dim,long int> & ib,
506  {
507  if (g.isInvalidGhost() == true || use_bx_def == true)
508  {return;}
509 
510  Box<dim,long int> sub_domain;
511 
512  if (use_bx_def == false)
513  {
514  sub_domain = gdb_ext.get(sub_id).Dbox;
515  sub_domain += gdb_ext.get(sub_id).origin;
516  }
517 
518  // Convert from Box<dim,St> to Box<dim,long int>
519  Box<dim,long int> sub_domain_other_exp = cd_sm.convertDomainSpaceIntoGridUnits(sub_domain_other,dec.periodicity());
520 
521  // translate sub_domain_other based on cmb
522  for (size_t i = 0 ; i < dim ; i++)
523  {
524  if (cmb.c[i] == 1)
525  {
526  sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) - ginfo.size(i));
527  sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) - ginfo.size(i));
528  }
529  else if (cmb.c[i] == -1)
530  {
531  sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) + ginfo.size(i));
532  sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) + ginfo.size(i));
533  }
534  }
535 
536  sub_domain_other_exp.enlarge(g);
537  if (sub_domain_other_exp.Intersect(sub_domain,ib) == false)
538  {
539  for (size_t i = 0 ; i < dim ; i++)
540  {ib.setHigh(i,ib.getLow(i) - 1);}
541  }
542  }
543 
544 
545 
550  {
551  // temporal vector used for computation
553 
554  if (init_i_g_box == true) return;
555 
556  // Get the grid info
557  auto g = cd_sm.getGrid();
558 
559  g_id_to_internal_ghost_box.resize(dec.getNNProcessors());
560 
561  // Get the number of near processors
562  for (size_t i = 0 ; i < dec.getNNProcessors() ; i++)
563  {
564  ig_box.add();
565  auto&& pib = ig_box.last();
566 
567  pib.prc = dec.IDtoProc(i);
568  for (size_t j = 0 ; j < dec.getProcessorNIGhost(i) ; j++)
569  {
570  // Get the internal ghost boxes and transform into grid units
571  ::Box<dim,St> ib_dom = dec.getProcessorIGhostBox(i,j);
572  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
573 
574  size_t sub_id = dec.getProcessorIGhostSub(i,j);
575  size_t r_sub = dec.getProcessorIGhostSSub(i,j);
576 
577  auto & n_box = dec.getNearSubdomains(dec.IDtoProc(i));
578 
579  set_for_adjustment(sub_id,
580  n_box.get(r_sub),dec.getProcessorIGhostPos(i,j),
581  ib,ghost_int);
582 
583  // Here we intersect the internal ghost box with the definition boxes
584  // this operation make sense when the grid is not defined in the full
585  // domain and we have to intersect the internal ghost box with all the box
586  // that define where the grid is defined
587  bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
588 
589  for (size_t k = 0 ; k < ibv.size() ; k++)
590  {
591  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
592  if (ibv.get(k).bx.isValid() == false)
593  {continue;}
594 
595  // save the box and the sub-domain id (it is calculated as the linearization of P1)
596  ::Box<dim,size_t> cvt = ibv.get(k).bx;
597 
598  i_box_id<dim> bid_t;
599  bid_t.box = cvt;
600  bid_t.g_id = dec.getProcessorIGhostId(i,j) | (k) << 52;
601 
602  bid_t.sub = convert_to_gdb_ext(dec.getProcessorIGhostSub(i,j),
603  ibv.get(k).id,
604  gdb_ext,
606 
607  bid_t.cmb = dec.getProcessorIGhostPos(i,j);
608  bid_t.r_sub = dec.getProcessorIGhostSSub(i,j);
609  pib.bid.add(bid_t);
610 
611  g_id_to_internal_ghost_box.get(i)[bid_t.g_id | (k) << 52 ] = pib.bid.size()-1;
612  }
613  }
614  }
615 
616  init_i_g_box = true;
617  }
618 
619 
624  {
625  // Get the grid info
626  auto g = cd_sm.getGrid();
627 
628  if (init_e_g_box == true) return;
629 
630  // Here we collect all the calculated internal ghost box in the sector different from 0 that this processor has
631 
633  openfpm::vector<size_t> prc_recv;
634  openfpm::vector<size_t> sz_recv;
635  openfpm::vector<openfpm::vector<Box_fix<dim>>> box_int_send(dec.getNNProcessors());
637 
638  for(size_t i = 0 ; i < dec.getNNProcessors() ; i++)
639  {
640  for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
641  {
642  box_int_send.get(i).add();
643  box_int_send.get(i).last().bx = ig_box.get(i).bid.get(j).box;
644  box_int_send.get(i).last().g_id = ig_box.get(i).bid.get(j).g_id;
645  box_int_send.get(i).last().r_sub = ig_box.get(i).bid.get(j).r_sub;
646  box_int_send.get(i).last().cmb = ig_box.get(i).bid.get(j).cmb;
647  }
648  prc.add(dec.IDtoProc(i));
649  }
650 
651  v_cl.SSendRecv(box_int_send,box_int_recv,prc,prc_recv,sz_recv);
652 
653  eg_box.resize(dec.getNNProcessors());
654 
655  for (size_t i = 0 ; i < eg_box.size() ; i++)
656  {eg_box.get(i).prc = dec.IDtoProc(i);}
657 
658  for (size_t i = 0 ; i < box_int_recv.size() ; i++)
659  {
660  size_t pib_cnt = 0;
661  size_t p_id = dec.ProctoID(prc_recv.get(i));
662  auto&& pib = eg_box.get(p_id);
663  pib.prc = prc_recv.get(i);
664 
665  eg_box.get(p_id).recv_pnt = 0;
666  eg_box.get(p_id).n_r_box = box_int_recv.get(i).size();
667 
668  // For each received internal ghost box
669  for (size_t j = 0 ; j < box_int_recv.get(i).size() ; j++)
670  {
671  size_t vol_recv = box_int_recv.get(i).get(j).bx.getVolumeKey();
672 
673  eg_box.get(p_id).recv_pnt += vol_recv;
674  size_t send_list_id = box_int_recv.get(i).get(j).r_sub;
675 
676  if (use_bx_def == true)
677  {
678  // First we understand if the internal ghost box sent intersect
679  // some local extended sub-domain.
680 
681  // eb_gid_list, for an explanation check the declaration
682  eb_gid_list.add();
683  eb_gid_list.last().e_id = p_id;
684 
685  // Now we have to check if a received external ghost box intersect one
686  // or more sub-grids
687  for (size_t k = 0 ; k < gdb_ext.size() ; k++)
688  {
689  Box<dim,long int> bx = gdb_ext.get(k).GDbox;
690  bx += gdb_ext.get(k).origin;
691 
692  Box<dim,long int> output;
693  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);
694 
695  // it intersect one sub-grid
696  if (bx.Intersect(flp_i,output))
697  {
698  // link
699 
700  size_t g_id = box_int_recv.get(i).get(j).g_id;
701  add_eg_box<dim>(k,box_int_recv.get(i).get(j).cmb,output,
702  g_id,
703  gdb_ext.get(k).origin,
704  box_int_recv.get(i).get(j).bx.getP1(),
705  pib.bid);
706 
707  eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
708 
710  }
711  }
712 
713  // now we check if exist a full match across the full intersected
714  // ghost parts
715 
716  bool no_match = true;
717  for (size_t k = 0 ; k < eb_gid_list.last().eb_list.size() ; k++)
718  {
719  size_t eb_id = eb_gid_list.last().eb_list.get(k);
720 
721  if (pib.bid.get(eb_id).g_e_box == box_int_recv.get(i).get(j).bx)
722  {
723  // full match found
724 
725  eb_gid_list.last().full_match = eb_id;
726  no_match = false;
727 
728  break;
729  }
730  }
731 
732  // This is the case where a full match has not been found. In this case we
733  // generate an additional gdb_ext and local grid with only external ghost
734 
735  if (no_match == true)
736  {
737  // Create a grid with the same size of the external ghost
738 
739  size_t sz[dim];
740  for (size_t s = 0 ; s < dim ; s++)
741  {sz[s] = box_int_recv.get(i).get(j).bx.getHigh(s) - box_int_recv.get(i).get(j).bx.getLow(s) + 1;}
742 
743  // Add an unlinked gdb_ext
744  // An unlinked gdb_ext is an empty domain with only a external ghost
745  // part
746  Box<dim,long int> output = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
747 
748  GBoxes<dim> tmp;
749  tmp.GDbox = box_int_recv.get(i).get(j).bx;
750  tmp.GDbox -= tmp.GDbox.getP1();
751  tmp.origin = output.getP1();
752  for (size_t s = 0 ; s < dim ; s++)
753  {
754  // we set an invalid box, there is no-domain
755  tmp.Dbox.setLow(s,0);
756  tmp.Dbox.setHigh(s,-1);
757  }
758  tmp.k = (size_t)-1;
759  gdb_ext.add(tmp);
760 
761  // create the local grid
762 
763  loc_grid.add();
764  loc_grid.last().resize(sz);
765 
766  // Add an external ghost box
767 
768  size_t g_id = box_int_recv.get(i).get(j).g_id;
769  add_eg_box<dim>(gdb_ext.size()-1,box_int_recv.get(i).get(j).cmb,output,
770  g_id,
771  gdb_ext.get(gdb_ext.size()-1).origin,
772  box_int_recv.get(i).get(j).bx.getP1(),
773  pib.bid);
774 
775  // now we map the received ghost box to the information of the
776  // external ghost box created
777  eb_gid_list.last().full_match = pib.bid.size() - 1;
778  eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
780  }
781 
782  // now we create lr_e_box
783 
784  size_t fm = eb_gid_list.last().full_match;
785  size_t sub_id = pib.bid.get(fm).sub;
786 
787  for ( ; pib_cnt < pib.bid.size() ; pib_cnt++)
788  {
789  pib.bid.get(pib_cnt).lr_e_box -= gdb_ext.get(sub_id).origin;
790  }
791 
792  }
793  else
794  {
795  // Get the list of the sent sub-domains
796  // and recover the id of the sub-domain from
797  // the sent list
798  const openfpm::vector<size_t> & s_sub = dec.getSentSubdomains(p_id);
799 
800  size_t sub_id = s_sub.get(send_list_id);
801 
802  e_box_id<dim> bid_t;
803  bid_t.sub = sub_id;
804  bid_t.cmb = box_int_recv.get(i).get(j).cmb;
805  bid_t.cmb.sign_flip();
806  ::Box<dim,long int> ib = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
807  bid_t.g_e_box = ib;
808  bid_t.g_id = box_int_recv.get(i).get(j).g_id;
809  // Translate in local coordinate
810  Box<dim,long int> tb = ib;
811  tb -= gdb_ext.get(sub_id).origin;
812  bid_t.l_e_box = tb;
813 
814  pib.bid.add(bid_t);
815  eb_gid_list.add();
816  eb_gid_list.last().eb_list.add(pib.bid.size()-1);
817  eb_gid_list.last().e_id = p_id;
818  eb_gid_list.last().full_match = pib.bid.size()-1;
819 
821  }
822  }
823  }
824 
825  init_e_g_box = true;
826  }
827 
832  {
834 
835  // Get the grid info
836  auto g = cd_sm.getGrid();
837 
838  if (init_local_i_g_box == true) return;
839 
840  // Get the number of sub-domains
841  for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
842  {
843  loc_ig_box.add();
844  auto&& pib = loc_ig_box.last();
845 
846  for (size_t j = 0 ; j < dec.getLocalNIGhost(i) ; j++)
847  {
848  if (use_bx_def == true)
849  {
850  // Get the internal ghost boxes and transform into grid units
851  ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
852  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
853 
854  // Here we intersect the internal ghost box with the definition boxes
855  // this operation make sense when the grid is not defined in the full
856  // domain and we have to intersect the internal ghost box with all the box
857  // that define where the grid is defined
858  bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
859 
860  for (size_t k = 0 ; k < ibv.size() ; k++)
861  {
862  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
863  if (ibv.get(k).bx.isValid() == false)
864  {continue;}
865 
866  pib.bid.add();
867  pib.bid.last().box = ibv.get(k).bx;
868 
869  pib.bid.last().sub_gdb_ext = convert_to_gdb_ext(i,
870  ibv.get(k).id,
871  gdb_ext,
873 
874  pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
875 
876  // It will be filled later
877  pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
878  }
879  }
880  else
881  {
882  // Get the internal ghost boxes and transform into grid units
883  ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
884  ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
885 
886  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
887  if (ib.isValid() == false)
888  continue;
889 
890  size_t sub_id = i;
891  size_t r_sub = dec.getLocalIGhostSub(i,j);
892 
893  set_for_adjustment(sub_id,dec.getSubDomain(r_sub),
894  dec.getLocalIGhostPos(i,j),ib,ghost_int);
895 
896  // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
897  if (ib.isValid() == false)
898  continue;
899 
900  pib.bid.add();
901  pib.bid.last().box = ib;
902  pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
903  pib.bid.last().k.add(dec.getLocalIGhostE(i,j));
904  pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
905  pib.bid.last().sub_gdb_ext = i;
906  }
907  }
908 
909  if (use_bx_def == true)
910  {
911  // unfortunately boxes that define where the grid is located can generate
912  // additional internal ghost boxes
913 
914  for (size_t j = gdb_ext_markers.get(i) ; j < gdb_ext_markers.get(i+1) ; j++)
915  {
916  // intersect within box in the save sub-domain
917 
918  for (size_t k = gdb_ext_markers.get(i) ; k < gdb_ext_markers.get(i+1) ; k++)
919  {
920  if (j == k) {continue;}
921 
922  // extend k and calculate the internal ghost box
923  Box<dim,long int> bx_e = gdb_ext.get(k).GDbox;
924  bx_e += gdb_ext.get(k).origin;
925  Box<dim,long int> bx = gdb_ext.get(j).Dbox;
926  bx += gdb_ext.get(j).origin;
927 
928  Box<dim,long int> output;
929  if (bx.Intersect(bx_e, output) == true)
930  {
931  pib.bid.add();
932 
933  pib.bid.last().box = output;
934 
935  pib.bid.last().sub_gdb_ext = j;
936  pib.bid.last().sub = i;
937 
938  // these ghost always in the quadrant zero
939  pib.bid.last().cmb.zero();
940 
941  }
942  }
943  }
944  }
945 
946  }
947 
948 
949  init_local_i_g_box = true;
950  }
951 
956  {
957  // Get the grid info
958  auto g = cd_sm.getGrid();
959 
960  if (init_local_e_g_box == true) return;
961 
962  loc_eg_box.resize(dec.getNSubDomain());
963 
964  // Get the number of sub-domain
965  for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
966  {
967  for (size_t j = 0 ; j < loc_ig_box.get(i).bid.size() ; j++)
968  {
969  long int volume_linked = 0;
970 
971  size_t le_sub = loc_ig_box.get(i).bid.get(j).sub;
972  auto & pib = loc_eg_box.get(le_sub);
973 
974  if (use_bx_def == true)
975  {
976 
977  // We check if an external local ghost box intersect one
978  // or more sub-grids
979  for (size_t k = 0 ; k < gdb_ext.size() ; k++)
980  {
981  Box<dim,long int> bx = gdb_ext.get(k).Dbox;
982  bx += gdb_ext.get(k).origin;
983 
984  Box<dim,long int> gbx = gdb_ext.get(k).GDbox;
985  gbx += gdb_ext.get(k).origin;
986 
987  Box<dim,long int> output;
988  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);
989 
990  bool intersect_domain = bx.Intersect(flp_i,output);
991  bool intersect_gdomain = gbx.Intersect(flp_i,output);
992 
993  // it intersect one sub-grid
994  if (intersect_domain == false && intersect_gdomain == true)
995  {
996  // fill the link variable
997  loc_ig_box.get(i).bid.get(j).k.add(pib.bid.size());
998  size_t s = loc_ig_box.get(i).bid.get(j).k.last();
999 
1000  comb<dim> cmb = loc_ig_box.get(i).bid.get(j).cmb;
1001  cmb.sign_flip();
1002 
1003  add_loc_eg_box(le_sub,
1004  loc_ig_box.get(i).bid.get(j).sub_gdb_ext,
1005  j,
1006  k,
1007  pib.bid,
1008  output,
1009  cmb);
1010 
1011 
1012  volume_linked += pib.bid.last().ebox.getVolumeKey();
1013  }
1014  }
1015  }
1016  else
1017  {
1018  size_t k = loc_ig_box.get(i).bid.get(j).sub;
1019  auto & pib = loc_eg_box.get(k);
1020 
1021  size_t s = loc_ig_box.get(i).bid.get(j).k.get(0);
1022  pib.bid.resize(dec.getLocalNEGhost(k));
1023 
1024  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);
1025  pib.bid.get(s).sub = dec.getLocalEGhostSub(k,s);
1026  pib.bid.get(s).cmb = loc_ig_box.get(i).bid.get(j).cmb;
1027  pib.bid.get(s).cmb.sign_flip();
1028  pib.bid.get(s).k = j;
1029  pib.bid.get(s).initialized = true;
1030  pib.bid.get(s).sub_gdb_ext = k;
1031  }
1032  }
1033  }
1034 
1035  init_local_e_g_box = true;
1036  }
1037 
1038 
1044  inline void check_size(const size_t (& g_sz)[dim])
1045  {
1046  for (size_t i = 0 ; i < dim ; i++)
1047  {
1048  if (g_sz[i] < 2)
1049  {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " distributed grids with size smaller than 2 are not supported\n";}
1050  }
1051  }
1052 
1058  inline void check_domain(const Box<dim,St> & dom)
1059  {
1060  for (size_t i = 0 ; i < dim ; i++)
1061  {
1062  if (dom.getLow(i) >= dom.getHigh(i))
1063  {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " error the simulation domain is invalid\n";}
1064  }
1065  }
1066 
1074  const Ghost<dim,long int> & g,
1075  bool use_bx_def)
1076  {
1077  // create gdb
1078  create_gdb_ext<dim,Decomposition>(gdb_ext,gdb_ext_markers,dec,cd_sm,bx_def,g,use_bx_def);
1079 
1080  size_t n_grid = gdb_ext.size();
1081 
1082  // create local grids for each hyper-cube
1083  loc_grid.resize(n_grid);
1084 
1085  // Size of the grid on each dimension
1086  size_t l_res[dim];
1087 
1088  // Allocate the grids
1089  for (size_t i = 0 ; i < n_grid ; i++)
1090  {
1091  Box<dim,long int> sp_tg = gdb_ext.get(i).GDbox;
1092 
1093  // Get the size of the local grid
1094  // The boxes indicate the extension of the index the size
1095  // is this extension +1
1096  // for example a 1D box (interval) from 0 to 3 in one dimension have
1097  // the points 0,1,2,3 = so a total of 4 points
1098  for (size_t j = 0 ; j < dim ; j++)
1099  {l_res[j] = (sp_tg.getHigh(j) >= 0)?(sp_tg.getHigh(j)+1):0;}
1100 
1101  // Set the dimensions of the local grid
1102  loc_grid.get(i).resize(l_res);
1103  }
1104  }
1105 
1106 
1113  inline void InitializeCellDecomposer(const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_old, const Box<dim,size_t> & ext)
1114  {
1115  // Initialize the cell decomposer
1116  cd_sm.setDimensions(cd_old,ext);
1117  }
1118 
1125  inline void InitializeCellDecomposer(const size_t (& g_sz)[dim], const size_t (& bc)[dim])
1126  {
1127  // check that the grid has valid size
1128  check_size(g_sz);
1129 
1130  // get the size of the cell decomposer
1131  size_t c_g[dim];
1132  getCellDecomposerPar<dim>(c_g,g_sz,bc);
1133 
1134  // Initialize the cell decomposer
1135  cd_sm.setDimensions(domain,c_g,0);
1136  }
1137 
1144  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>())
1145  {
1146  // fill the global size of the grid
1147  for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
1148 
1149  // Get the number of processor and calculate the number of sub-domain
1150  // for decomposition
1151  size_t n_proc = v_cl.getProcessingUnits();
1152  size_t n_sub = n_proc * v_sub_unit_factor;
1153 
1154  // Calculate the maximum number (before merging) of sub-domain on
1155  // each dimension
1156  size_t div[dim];
1157  for (size_t i = 0 ; i < dim ; i++)
1158  {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/dim));}
1159 
1160  if (g_dist.size(0) != 0)
1161  {
1162  for (size_t i = 0 ; i < dim ; i++)
1163  {div[i] = g_dist.size(i);}
1164  }
1165 
1166  // Create the sub-domains
1167  dec.setParameters(div,domain,bc,ghost);
1168  dec.decompose(dec_options::DEC_SKIP_ICELL);
1169  }
1170 
1176  inline void InitializeStructures(const size_t (& g_sz)[dim])
1177  {
1178  // an empty
1180 
1181  // Ghost zero
1182  Ghost<dim,long int> zero;
1183 
1184  InitializeStructures(g_sz,empty,zero,false);
1185  }
1186 
1194  inline void InitializeStructures(const size_t (& g_sz)[dim],
1196  const Ghost<dim,long int> & g,
1197  bool use_bx_def)
1198  {
1199  // fill the global size of the grid
1200  for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
1201 
1202  // Create local grid
1203  Create(bx,g,use_bx_def);
1204  }
1205 
1206  // Ghost as integer
1208 
1209 protected:
1210 
1219  {
1220  return gdb_ext.get(i).Dbox;
1221  }
1222 
1231  static inline Ghost<dim,St> convert_ghost(const Ghost<dim,long int> & gd, const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_sm)
1232  {
1233  Ghost<dim,St> gc;
1234 
1235  // get the grid spacing
1236  Box<dim,St> sp = cd_sm.getCellBox();
1237 
1238  // enlarge 0.001 of the spacing
1239  sp.magnify_fix_P1(1.1);
1240 
1241  // set the ghost
1242  for (size_t i = 0 ; i < dim ; i++)
1243  {
1244  gc.setLow(i,gd.getLow(i)*(sp.getHigh(i)));
1245  gc.setHigh(i,gd.getHigh(i)*(sp.getHigh(i)));
1246  }
1247 
1248  return gc;
1249  }
1250 
1256  void setDecompositionGranularity(size_t n_sub)
1257  {
1258  this->v_sub_unit_factor = n_sub;
1259  }
1260 
1261  void reset_ghost_structures()
1262  {
1264  ig_box.clear();
1265  init_i_g_box = false;
1266 
1267  eg_box.clear();
1268  eb_gid_list.clear();
1269  init_e_g_box = false;
1270 
1271  init_local_i_g_box = false;
1272  loc_ig_box.clear();
1273 
1274  init_local_e_g_box = false;
1275  loc_eg_box.clear();
1276  }
1277 
1278 public:
1279 
1282 
1285 
1287  typedef T value_type;
1288 
1290  typedef St stype;
1291 
1293  typedef Memory memory_type;
1294 
1297 
1299  static const unsigned int dims = dim;
1300 
1306  inline const Box<dim,St> getDomain() const
1307  {
1308  return domain;
1309  }
1310 
1311 
1318  return loc_grid;
1319  }
1320 
1321 
1330  {
1331  return pmul(Point<dim,St>(gdb_ext.get(i).origin), cd_sm.getCellBox().getP2()) + getDomain().getP1();
1332  }
1333 
1341  inline St spacing(size_t i) const
1342  {
1343  return cd_sm.getCellBox().getHigh(i);
1344  }
1345 
1351  size_t size() const
1352  {
1353  return ginfo_v.size();
1354  }
1355 
1362  void setBackgroundValue(T & bv)
1363  {
1364  setBackground_impl<T,decltype(loc_grid)> func(bv,loc_grid);
1365  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop>>(func);
1366  }
1367 
1374  template<unsigned int p>
1375  void setBackgroundValue(const typename boost::mpl::at<typename T::type,boost::mpl::int_<p>>::type & bv)
1376  {
1377  for (size_t i = 0 ; i < loc_grid.size() ; i++)
1378  {loc_grid.get(i).template setBackgroundValue<p>(bv);}
1379  }
1380 
1389  size_t size_local_inserted() const
1390  {
1391  size_t lins = 0;
1392 
1393  for (size_t i = 0 ; i < loc_grid.size() ; i++)
1394  {lins += loc_grid.get(i).size_inserted();}
1395 
1396  return lins;
1397  }
1398 
1406  size_t size(size_t i) const
1407  {
1408  return ginfo_v.size(i);
1409  }
1410 
1417  :grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>(g),
1418  domain(g.domain),
1419  ghost(g.ghost),
1420  ghost_int(g.ghost_int),
1421  loc_grid(g.loc_grid),
1423  dec(g.dec),
1425  gdb_ext(g.gdb_ext),
1428  cd_sm(g.cd_sm),
1429  v_cl(g.v_cl),
1430  prp_names(g.prp_names),
1433  ginfo(g.ginfo),
1434  ginfo_v(g.ginfo_v),
1437  {
1438 #ifdef SE_CLASS2
1439  check_new(this,8,GRID_DIST_EVENT,4);
1440 #endif
1441 
1442  for (size_t i = 0 ; i < dim ; i++)
1443  {g_sz[i] = g.g_sz[i];}
1444  }
1445 
1456  template<typename H>
1457  grid_dist_id(const grid_dist_id<dim,St,H,typename Decomposition::base_type,Memory,grid_cpu<dim,H>> & g,
1458  const Ghost<dim,long int> & gh,
1459  Box<dim,size_t> ext)
1460  :ghost_int(gh),dec(create_vcluster()),v_cl(create_vcluster())
1461  {
1462 #ifdef SE_CLASS2
1463  check_new(this,8,GRID_DIST_EVENT,4);
1464 #endif
1465 
1466  size_t ext_dim[dim];
1467  for (size_t i = 0 ; i < dim ; i++) {ext_dim[i] = g.getGridInfoVoid().size(i) + ext.getKP1().get(i) + ext.getKP2().get(i);}
1468 
1469  // Set the grid info of the extended grid
1470  ginfo.setDimensions(ext_dim);
1471  ginfo_v.setDimensions(ext_dim);
1472 
1473  InitializeCellDecomposer(g.getCellDecomposer(),ext);
1474 
1475  ghost = convert_ghost(gh,cd_sm);
1476 
1477  // Extend the grid by the extension part and calculate the domain
1478 
1479  for (size_t i = 0 ; i < dim ; i++)
1480  {
1481  g_sz[i] = g.size(i) + ext.getLow(i) + ext.getHigh(i);
1482 
1483  if (g.getDecomposition().periodicity(i) == NON_PERIODIC)
1484  {
1485  this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i) - g.spacing(i) / 2.0);
1486  this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i) + g.spacing(i) / 2.0);
1487  }
1488  else
1489  {
1490  this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i));
1491  this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i));
1492  }
1493  }
1494 
1495  dec.setParameters(g.getDecomposition(),ghost,this->domain);
1496 
1497  // an empty
1499 
1500  InitializeStructures(g.getGridInfoVoid().getSize(),empty,gh,false);
1501  }
1502 
1510  template<typename Decomposition2>
1511  grid_dist_id(const Decomposition2 & dec,
1512  const size_t (& g_sz)[dim],
1513  const Ghost<dim,St> & ghost)
1514  :domain(dec.getDomain()),ghost(ghost),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),
1516  {
1517 #ifdef SE_CLASS2
1518  check_new(this,8,GRID_DIST_EVENT,4);
1519 #endif
1520 
1521  InitializeCellDecomposer(g_sz,dec.periodicity());
1522 
1523  this->dec = dec.duplicate(ghost);
1524 
1526  }
1527 
1535  grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1536  const Ghost<dim,St> & ghost)
1538  ginfo_v(g_sz),v_cl(create_vcluster()),ghost_int(INVALID_GHOST)
1539  {
1540 #ifdef SE_CLASS2
1541  check_new(this,8,GRID_DIST_EVENT,4);
1542 #endif
1543 
1544  InitializeCellDecomposer(g_sz,dec.periodicity());
1545 
1546  this->dec = dec.duplicate(ghost);
1547 
1549  }
1550 
1560  grid_dist_id(const Decomposition & dec, const size_t (& g_sz)[dim],
1561  const Ghost<dim,long int> & g)
1562  :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1564  {
1565  InitializeCellDecomposer(g_sz,dec.periodicity());
1566 
1567  ghost = convert_ghost(g,cd_sm);
1568  this->dec = dec.duplicate(ghost);
1569 
1570  // an empty
1572 
1573  // Initialize structures
1574  InitializeStructures(g_sz,empty,g,false);
1575  }
1576 
1586  template<typename Decomposition2>
1587  grid_dist_id(const Decomposition2 & dec, const size_t (& g_sz)[dim],
1588  const Ghost<dim,long int> & g)
1589  :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1591  {
1592  InitializeCellDecomposer(g_sz,dec.periodicity());
1593 
1594  ghost = convert_ghost(g,cd_sm);
1595  this->dec = dec.duplicate(ghost);
1596 
1597  // an empty
1599 
1600  // Initialize structures
1601  InitializeStructures(g_sz,empty,g,false);
1602  }
1603 
1613  grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1614  const Ghost<dim,long int> & g)
1615  :domain(dec.getDomain()),dec(dec),v_cl(create_vcluster()),ginfo(g_sz),
1616  ginfo_v(g_sz),ghost_int(g)
1617  {
1618 #ifdef SE_CLASS2
1619  check_new(this,8,GRID_DIST_EVENT,4);
1620 #endif
1621  InitializeCellDecomposer(g_sz,dec.periodicity());
1622 
1623  ghost = convert_ghost(g,cd_sm);
1624  this->dec = dec.duplicate(ghost);
1625 
1626  // an empty
1628 
1629  // Initialize structures
1630  InitializeStructures(g_sz,empty,g,false);
1631  }
1632 
1642  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g, size_t opt = 0)
1643  :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1644  {
1645  }
1646 
1656  grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g, size_t opt = 0)
1657  :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1658  {
1659  }
1660 
1671  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)
1672  :domain(domain),ghost(g),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1673  {
1674 #ifdef SE_CLASS2
1675  check_new(this,8,GRID_DIST_EVENT,4);
1676 #endif
1677 
1678  if (opt >> 32 != 0)
1679  {this->setDecompositionGranularity(opt >> 32);}
1680 
1681  check_domain(domain);
1685  }
1686 
1687 
1698  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>())
1699  :domain(domain),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1700  {
1701 #ifdef SE_CLASS2
1702  check_new(this,8,GRID_DIST_EVENT,4);
1703 #endif
1704 
1705  if (opt >> 32 != 0)
1706  {this->setDecompositionGranularity(opt >> 32);}
1707 
1708  check_domain(domain);
1710 
1711  ghost = convert_ghost(g,cd_sm);
1712 
1713  InitializeDecomposition(g_sz,p.bc,g_dec);
1714 
1715  // an empty
1717 
1718  // Initialize structures
1719  InitializeStructures(g_sz,empty,g,false);
1720  }
1721 
1722 
1737  grid_dist_id(const size_t (& g_sz)[dim],
1738  const Box<dim,St> & domain,
1739  const Ghost<dim,long int> & g,
1740  const periodicity<dim> & p,
1742  :domain(domain),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz),gint(g)
1743  {
1744 #ifdef SE_CLASS2
1745  check_new(this,8,GRID_DIST_EVENT,4);
1746 #endif
1747 
1750 
1751  ghost = convert_ghost(g,cd_sm);
1752 
1755  this->bx_def = bx_def;
1756  this->use_bx_def = true;
1757  }
1758 
1764  const grid_sm<dim,T> & getGridInfo() const
1765  {
1766 #ifdef SE_CLASS2
1767  check_valid(this,8);
1768 #endif
1769  return ginfo;
1770  }
1771 
1778  {
1779 #ifdef SE_CLASS2
1780  check_valid(this,8);
1781 #endif
1782  return ginfo_v;
1783  }
1784 
1791  {
1792 #ifdef SE_CLASS2
1793  check_valid(this,8);
1794 #endif
1795  return dec;
1796  }
1797 
1804  {
1805 #ifdef SE_CLASS2
1806  check_valid(this,8);
1807 #endif
1808  return dec;
1809  }
1810 
1816  const CellDecomposer_sm<dim,St,shift<dim,St>> & getCellDecomposer() const
1817  {
1818 #ifdef SE_CLASS2
1819  check_valid(this,8);
1820 #endif
1821  return cd_sm;
1822  }
1823 
1831  bool isInside(const grid_key_dx<dim> & gk) const
1832  {
1833 #ifdef SE_CLASS2
1834  check_valid(this,8);
1835 #endif
1836  for (size_t i = 0 ; i < dim ; i++)
1837  {
1838  if (gk.get(i) < 0 || gk.get(i) >= (long int)g_sz[i])
1839  {return false;}
1840  }
1841 
1842  return true;
1843  }
1844 
1850  size_t getLocalDomainSize() const
1851  {
1852 #ifdef SE_CLASS2
1853  check_valid(this,8);
1854 #endif
1855  size_t total = 0;
1856 
1857  for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1858  {
1859  total += gdb_ext.get(i).Dbox.getVolumeKey();
1860  }
1861 
1862  return total;
1863  }
1864 
1871  {
1872 #ifdef SE_CLASS2
1873  check_valid(this,8);
1874 #endif
1875  size_t total = 0;
1876 
1877  for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1878  {
1879  total += gdb_ext.get(i).GDbox.getVolumeKey();
1880  }
1881 
1882  return total;
1883  }
1884 
1885 
1892  {
1893 #ifdef SE_CLASS2
1894  check_valid(this,8);
1895 #endif
1896  return gdb_ext;
1897  }
1898 
1905  {
1906 #ifdef SE_CLASS2
1907  check_valid(this,8);
1908 #endif
1909  gdb_ext_global.clear();
1910 
1912  v_cl.execute();
1913 
1914  size_t size_r;
1915  size_t size = gdb_ext_global.size();
1916 
1917  if (v_cl.getProcessUnitID() == 0)
1918  {
1919  for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1920  v_cl.send(i,0,&size,sizeof(size_t));
1921 
1922  size_r = size;
1923  }
1924  else
1925  v_cl.recv(0,0,&size_r,sizeof(size_t));
1926 
1927  v_cl.execute();
1928 
1929  gdb_ext_global.resize(size_r);
1930 
1931 
1932  if (v_cl.getProcessUnitID() == 0)
1933  {
1934  for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1935  v_cl.send(i,0,gdb_ext_global);
1936  }
1937  else
1938  v_cl.recv(0,0,gdb_ext_global);
1939 
1940  v_cl.execute();
1941  }
1942 
1943 
1950  decltype(device_grid::type_of_subiterator()),
1951  FREE>
1953  {
1954 #ifdef SE_CLASS2
1955  check_valid(this,8);
1956 #endif
1957 
1959  grid_key_dx<dim> one;
1960  one.one();
1961  stop = stop - one;
1962 
1964  decltype(device_grid::type_of_subiterator()),
1965  FREE> it(loc_grid_old,gdb_ext_old,stop);
1966 
1967  return it;
1968  }
1969 
1981  {
1983  return it_dec;
1984  }
1985 
1986 #ifdef __NVCC__
1987 
1992  template<typename lambda_t2>
1993  void setPoints(lambda_t2 f2)
1994  {
1995  auto it = getGridIteratorGPU();
1996 
1997  it.template launch<1>(launch_set_dense<dim>(),f2);
1998  }
1999 
2006  template<typename lambda_t2>
2007  void setPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t2 f2)
2008  {
2009  auto it = getGridIteratorGPU(k1,k2);
2010 
2011  it.template launch<0>(launch_set_dense<dim>(),f2);
2012  }
2013 
2019  template<typename lambda_t1, typename lambda_t2>
2020  void addPoints(lambda_t1 f1, lambda_t2 f2)
2021  {
2022  auto it = getGridIteratorGPU();
2023  it.setGPUInsertBuffer(1);
2024 
2025  it.template launch<1>(launch_insert_sparse(),f1,f2);
2026  }
2027 
2035  template<typename lambda_t1, typename lambda_t2>
2036  void addPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t1 f1, lambda_t2 f2)
2037  {
2038  auto it = getGridIteratorGPU(k1,k2);
2039  it.setGPUInsertBuffer(1);
2040 
2041  it.template launch<1>(launch_insert_sparse(),f1,f2);
2042  }
2043 
2058  getGridIteratorGPU(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop)
2059  {
2061  return it_dec;
2062  }
2063 
2075  getGridIteratorGPU()
2076  {
2078  return it_dec;
2079  }
2080 
2081 #endif
2082 
2094  {
2096  return it_dec;
2097  }
2098 
2110  {
2111  grid_key_dx<dim> start;
2112  grid_key_dx<dim> stop;
2113  for (size_t i = 0; i < dim; i++)
2114  {
2115  start.set_d(i, 0);
2116  stop.set_d(i, g_sz[i] - 1);
2117  }
2118 
2120  return it_dec;
2121  }
2122 
2129  decltype(device_grid::type_of_subiterator()),FREE>
2131  {
2132 #ifdef SE_CLASS2
2133  check_valid(this,8);
2134 #endif
2135 
2137  grid_key_dx<dim> one;
2138  one.one();
2139  stop = stop - one;
2140 
2142  decltype(device_grid::type_of_subiterator()),
2143  FREE> it(loc_grid,gdb_ext,stop);
2144 
2145  return it;
2146  }
2147 
2155  template<unsigned int Np>
2157  decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
2158  FREE,
2160  getDomainIteratorStencil(const grid_key_dx<dim> (& stencil_pnt)[Np]) const
2161  {
2162 #ifdef SE_CLASS2
2163  check_valid(this,8);
2164 #endif
2165 
2167  grid_key_dx<dim> one;
2168  one.one();
2169  stop = stop - one;
2170 
2172  decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
2173  FREE,
2174  stencil_offset_compute<dim,Np>> it(loc_grid,gdb_ext,stop,stencil_pnt);
2175 
2176  return it;
2177  }
2178 
2185  decltype(device_grid::type_of_iterator()),
2186  FIXED>
2188  {
2189 #ifdef SE_CLASS2
2190  check_valid(this,8);
2191 #endif
2192  grid_key_dx<dim> stop;
2193  for (size_t i = 0 ; i < dim ; i++)
2194  {stop.set_d(i,0);}
2195 
2197  decltype(device_grid::type_of_iterator()),
2198  FIXED> it(loc_grid,gdb_ext,stop);
2199 
2200  return it;
2201  }
2202 
2217  const grid_key_dx<dim> & stop) const
2218  {
2219 #ifdef SE_CLASS2
2220  check_valid(this,8);
2221 #endif
2223 
2224  return it;
2225  }
2226 
2239  grid_dist_iterator_sub<dim,device_grid> getSubDomainIterator(const long int (& start)[dim], const long int (& stop)[dim]) const
2240  {
2242 
2243  return it;
2244  }
2245 
2248  {
2249 #ifdef SE_CLASS2
2250  check_delete(this);
2251 #endif
2252  dec.decRef();
2253  }
2254 
2261  {
2262 #ifdef SE_CLASS2
2263  check_valid(this,8);
2264 #endif
2265  return v_cl;
2266  }
2267 
2273  {
2274  for (int i = 0 ; i < loc_grid.size() ; i++)
2275  {
2276  loc_grid.get(i).removeUnusedBuffers();
2277  }
2278  }
2279 
2285  bool is_staggered() const
2286  {
2287  return false;
2288  }
2289 
2300  template <typename bg_key> inline void remove(const grid_dist_key_dx<dim,bg_key> & v1)
2301  {
2302 #ifdef SE_CLASS2
2303  check_valid(this,8);
2304 #endif
2305  return loc_grid.get(v1.getSub()).remove(v1.getKey());
2306  }
2307 
2318  template <typename bg_key> inline void remove_no_flush(const grid_dist_key_dx<dim,bg_key> & v1)
2319  {
2320 #ifdef SE_CLASS2
2321  check_valid(this,8);
2322 #endif
2323  return loc_grid.get(v1.getSub()).remove_no_flush(v1.getKey());
2324  }
2325 
2326 
2327  template<typename ... v_reduce>
2328  void flush(flush_type opt = flush_type::FLUSH_ON_HOST)
2329  {
2330  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2331  {
2332  loc_grid.get(i).template flush<v_reduce ...>(v_cl.getGpuContext(),opt);
2333  }
2334  }
2335 
2346  inline void flush_remove()
2347  {
2348 #ifdef SE_CLASS2
2349  check_valid(this,8);
2350 #endif
2351  for (size_t i = 0 ; i < loc_grid.size() ; i++)
2352  {loc_grid.get(i).flush_remove();}
2353  }
2354 
2368  template <unsigned int p,typename bg_key>inline auto insert(const grid_dist_key_dx<dim,bg_key> & v1)
2369  -> decltype(loc_grid.get(v1.getSub()).template insert<p>(v1.getKey()))
2370  {
2371 #ifdef SE_CLASS2
2372  check_valid(this,8);
2373 #endif
2374 
2375  return loc_grid.get(v1.getSub()).template insert<p>(v1.getKey());
2376  }
2377 
2378 
2395  template <unsigned int p,typename bg_key>inline auto insertFlush(const grid_dist_key_dx<dim,bg_key> & v1)
2396  -> decltype(loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey()))
2397  {
2398 #ifdef SE_CLASS2
2399  check_valid(this,8);
2400 #endif
2401 
2402  return loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey());
2403  }
2404 
2421  template <typename bg_key>inline auto insertFlush(const grid_dist_key_dx<dim,bg_key> & v1)
2422  -> decltype(loc_grid.get(v1.getSub()).insertFlush(v1.getKey()))
2423  {
2424 #ifdef SE_CLASS2
2425  check_valid(this,8);
2426 #endif
2427 
2428  return loc_grid.get(v1.getSub()).insertFlush(v1.getKey());
2429  }
2430 
2439  template <unsigned int p, typename bg_key>
2440  inline auto get(const grid_dist_key_dx<dim,bg_key> & v1) const
2441  -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
2442  {
2443 #ifdef SE_CLASS2
2444  check_valid(this,8);
2445 #endif
2446  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2447  }
2448 
2449 
2458  template <unsigned int p, typename bg_key>
2459  inline auto get(const grid_dist_key_dx<dim,bg_key> & v1)
2460  -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2461  {
2462 #ifdef SE_CLASS2
2463  check_valid(this,8);
2464 #endif
2465  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2466  }
2467 
2476  template <unsigned int p = 0>
2477  inline auto get(const grid_dist_g_dx<device_grid> & v1) const
2478  -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2479  {
2480 #ifdef SE_CLASS2
2481  check_valid(this,8);
2482 #endif
2483  return v1.getSub()->template get<p>(v1.getKey());
2484  }
2485 
2494  template <unsigned int p = 0>
2495  inline auto get(const grid_dist_g_dx<device_grid> & v1) -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2496  {
2497 #ifdef SE_CLASS2
2498  check_valid(this,8);
2499 #endif
2500  return v1.getSub()->template get<p>(v1.getKey());
2501  }
2502 
2511  template <unsigned int p = 0>
2512  inline auto get(const grid_dist_lin_dx & v1) const -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2513  {
2514 #ifdef SE_CLASS2
2515  check_valid(this,8);
2516 #endif
2517  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2518  }
2519 
2528  template <unsigned int p = 0>
2529  inline auto get(const grid_dist_lin_dx & v1) -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2530  {
2531 #ifdef SE_CLASS2
2532  check_valid(this,8);
2533 #endif
2534  return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2535  }
2536 
2545  template <typename bg_key>
2547  {
2548 #ifdef SE_CLASS2
2549  check_valid(this,8);
2550 #endif
2551  Point<dim,St> p;
2552 
2553  for (int i = 0 ; i < dim ; i++)
2554  {
2555  p.get(i) = (gdb_ext.get(v1.getSub()).origin.get(i) + v1.getKeyRef().get(i)) * this->spacing(i) + domain.getLow(i);
2556  }
2557 
2558  return p;
2559  }
2560 
2568  template<typename bg_key>
2569  inline bool existPoint(const grid_dist_key_dx<dim,bg_key> & v1) const
2570  {
2571  return loc_grid.get(v1.getSub()).existPoint(v1.getKey());
2572  }
2573 
2582  template <unsigned int p = 0, typename bgkey>
2583  inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) const -> decltype(this->template get<p>(v1))
2584  {
2585  return this->template get<p>(v1);
2586  }
2587 
2596  template <unsigned int p = 0, typename bgkey>
2597  inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) -> decltype(this->template get<p>(v1))
2598  {
2599  return this->template get<p>(v1);
2600  }
2601 
2607  template<int... prp> void ghost_get(size_t opt = 0)
2608  {
2609 #ifdef SE_CLASS2
2610  check_valid(this,8);
2611 #endif
2612 
2613  // Convert the ghost internal boxes into grid unit boxes
2614  create_ig_box();
2615 
2616  // Convert the ghost external boxes into grid unit boxes
2617  create_eg_box();
2618 
2619  // Convert the local ghost internal boxes into grid unit boxes
2621 
2622  // Convert the local external ghost boxes into grid unit boxes
2624 
2626  eg_box,
2627  loc_ig_box,
2628  loc_eg_box,
2629  gdb_ext,
2630  eb_gid_list,
2631  use_bx_def,
2632  loc_grid,
2633  ginfo_v,
2635  opt);
2636  }
2637 
2643  template<template<typename,typename> class op,int... prp> void ghost_put()
2644  {
2645 #ifdef SE_CLASS2
2646  check_valid(this,8);
2647 #endif
2648 
2649  // Convert the ghost internal boxes into grid unit boxes
2650  create_ig_box();
2651 
2652  // Convert the ghost external boxes into grid unit boxes
2653  create_eg_box();
2654 
2655  // Convert the local ghost internal boxes into grid unit boxes
2657 
2658  // Convert the local external ghost boxes into grid unit boxes
2660 
2662  ig_box,
2663  eg_box,
2664  loc_ig_box,
2665  loc_eg_box,
2666  gdb_ext,
2667  loc_grid,
2669  }
2670 
2671 
2685  {
2686  if (T::noPointers() == true && use_memcpy)
2687  {
2688  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2689  {
2690  auto & gs_src = this->get_loc_grid(i).getGrid();
2691 
2692  long int start = gs_src.LinId(gdb_ext.get(i).Dbox.getKP1());
2693  long int stop = gs_src.LinId(gdb_ext.get(i).Dbox.getKP2());
2694 
2695  if (stop < start) {continue;}
2696 
2697  void * dst = static_cast<void *>(static_cast<char *>(this->get_loc_grid(i).getPointer()) + start*sizeof(T));
2698  void * src = static_cast<void *>(static_cast<char *>(g.get_loc_grid(i).getPointer()) + start*sizeof(T));
2699 
2700  memcpy(dst,src,sizeof(T) * (stop + 1 - start));
2701  }
2702  }
2703  else
2704  {
2705  grid_key_dx<dim> cnt[1];
2706  cnt[0].zero();
2707 
2708  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2709  {
2710  auto & dst = this->get_loc_grid(i);
2711  auto & src = g.get_loc_grid(i);
2712 
2713  auto it = this->get_loc_grid_iterator_stencil(i,cnt);
2714 
2715  while (it.isNext())
2716  {
2717  // center point
2718  auto Cp = it.template getStencil<0>();
2719 
2720  dst.insert_o(Cp) = src.get_o(Cp);
2721 
2722  ++it;
2723  }
2724  }
2725  }
2726 
2727  return *this;
2728  }
2729 
2743  {
2744  grid_key_dx<dim> cnt[1];
2745  cnt[0].zero();
2746 
2747  for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2748  {
2749  auto & dst = this->get_loc_grid(i);
2750  auto & src = g.get_loc_grid(i);
2751 
2752  dst = src;
2753  }
2754  return *this;
2755  }
2756 
2763  {
2764  return cd_sm.getCellBox().getP2();
2765  }
2766 
2778  {
2779 #ifdef SE_CLASS2
2780  check_valid(this,8);
2781 #endif
2782  // Get the sub-domain id
2783  size_t sub_id = k.getSub();
2784 
2785  grid_key_dx<dim> k_glob = k.getKey();
2786 
2787  // shift
2788  k_glob = k_glob + gdb_ext.get(sub_id).origin;
2789 
2790  return k_glob;
2791  }
2792 
2801  template <typename Model>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2802  {
2803  CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2804 
2806  auto & dist = getDecomposition().getDistribution();
2807 
2808  cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2809 
2810  // Invert the id to positional
2811 
2812  Point<dim,St> p;
2813  for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2814  {
2815  dist.getSubSubDomainPos(i,p);
2816  dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1 + md.resolution(p));
2817  }
2818 
2819  dec.computeCommunicationAndMigrationCosts(ts);
2820 
2821  dist.setDistTol(md.distributionTol());
2822  }
2823 
2828  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, unsigned int N, typename lambda_f, typename ... ArgsT >
2829  void conv(int (& stencil)[N][dim], grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2830  {
2831  for (int i = 0 ; i < loc_grid.size() ; i++)
2832  {
2833  Box<dim,long int> inte;
2834 
2835  Box<dim,long int> base;
2836  for (int j = 0 ; j < dim ; j++)
2837  {
2838  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2839  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2840  }
2841 
2842  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2843 
2844  bool overlap = dom.Intersect(base,inte);
2845 
2846  if (overlap == true)
2847  {
2848  loc_grid.get(i).template conv<prop_src,prop_dst,stencil_size>(stencil,inte.getKP1(),inte.getKP2(),func,args...);
2849  }
2850  }
2851  }
2852 
2857  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2858  void conv_cross(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2859  {
2860  for (int i = 0 ; i < loc_grid.size() ; i++)
2861  {
2862  Box<dim,long int> inte;
2863 
2864  Box<dim,long int> base;
2865  for (int j = 0 ; j < dim ; j++)
2866  {
2867  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2868  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2869  }
2870 
2871  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2872 
2873  bool overlap = dom.Intersect(base,inte);
2874 
2875  if (overlap == true)
2876  {
2877  loc_grid.get(i).template conv_cross<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2878  }
2879  }
2880  }
2881 
2886  template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2887  void conv_cross_b(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2888  {
2889  for (int i = 0 ; i < loc_grid.size() ; i++)
2890  {
2891  Box<dim,long int> inte;
2892 
2893  Box<dim,long int> base;
2894  for (int j = 0 ; j < dim ; j++)
2895  {
2896  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2897  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2898  }
2899 
2900  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2901 
2902  bool overlap = dom.Intersect(base,inte);
2903 
2904  if (overlap == true)
2905  {
2906  loc_grid.get(i).template conv_cross_b<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2907  }
2908  }
2909  }
2910 
2915  template<unsigned int stencil_size, typename v_type, typename lambda_f, typename ... ArgsT >
2916  void conv_cross_ids(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2917  {
2918  for (int i = 0 ; i < loc_grid.size() ; i++)
2919  {
2920  Box<dim,long int> inte;
2921 
2922  Box<dim,long int> base;
2923  for (int j = 0 ; j < dim ; j++)
2924  {
2925  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2926  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2927  }
2928 
2929  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2930 
2931  bool overlap = dom.Intersect(base,inte);
2932 
2933  if (overlap == true)
2934  {
2935  loc_grid.get(i).template conv_cross_ids<stencil_size,v_type>(inte.getKP1(),inte.getKP2(),func,args...);
2936  }
2937  }
2938  }
2939 
2944  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 >
2945  void conv2(int (& stencil)[N][dim], grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2946  {
2947  for (int i = 0 ; i < loc_grid.size() ; i++)
2948  {
2949  Box<dim,long int> inte;
2950 
2951  Box<dim,long int> base;
2952  for (int j = 0 ; j < dim ; j++)
2953  {
2954  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2955  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2956  }
2957 
2958  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2959 
2960  bool overlap = dom.Intersect(base,inte);
2961 
2962  if (overlap == true)
2963  {
2964  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...);
2965  }
2966  }
2967  }
2968 
2973  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 >
2974  void conv2(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2975  {
2976  for (int i = 0 ; i < loc_grid.size() ; i++)
2977  {
2978  Box<dim,long int> inte;
2979 
2980  Box<dim,long int> base;
2981  for (int j = 0 ; j < dim ; j++)
2982  {
2983  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2984  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2985  }
2986 
2987  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2988 
2989  bool overlap = dom.Intersect(base,inte);
2990 
2991  if (overlap == true)
2992  {
2993  loc_grid.get(i).template conv2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2994  }
2995  }
2996  }
2997 
3002  template<unsigned int prop_src1, unsigned int prop_dst1, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
3003  void conv(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
3004  {
3005  for (int i = 0 ; i < loc_grid.size() ; i++)
3006  {
3007  Box<dim,long int> inte;
3008 
3009  Box<dim,long int> base;
3010  for (int j = 0 ; j < dim ; j++)
3011  {
3012  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3013  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3014  }
3015 
3016  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3017 
3018  bool overlap = dom.Intersect(base,inte);
3019 
3020  if (overlap == true)
3021  {
3022  loc_grid.get(i).template conv<prop_src1,prop_dst1,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3023  }
3024  }
3025  }
3026 
3031  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 >
3032  void conv2_b(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
3033  {
3034  for (int i = 0 ; i < loc_grid.size() ; i++)
3035  {
3036  Box<dim,long int> inte;
3037 
3038  Box<dim,long int> base;
3039  for (int j = 0 ; j < dim ; j++)
3040  {
3041  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3042  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3043  }
3044 
3045  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3046 
3047  bool overlap = dom.Intersect(base,inte);
3048 
3049  if (overlap == true)
3050  {
3051  loc_grid.get(i).template conv2_b<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3052  }
3053  }
3054  }
3055 
3060  template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_src3,
3061  unsigned int prop_dst1, unsigned int prop_dst2, unsigned int prop_dst3,
3062  unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
3063  void conv3_b(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
3064  {
3065  for (int i = 0 ; i < loc_grid.size() ; i++)
3066  {
3067  Box<dim,long int> inte;
3068 
3069  Box<dim,long int> base;
3070  for (int j = 0 ; j < dim ; j++)
3071  {
3072  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3073  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3074  }
3075 
3076  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3077 
3078  bool overlap = dom.Intersect(base,inte);
3079 
3080  if (overlap == true)
3081  {
3082  loc_grid.get(i).template conv3_b<prop_src1,prop_src2,prop_src3,prop_dst1,prop_dst2,prop_dst3,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3083  }
3084  }
3085  }
3086 
3087  template<typename NNtype>
3088  void findNeighbours()
3089  {
3090  for (int i = 0 ; i < loc_grid.size() ; i++)
3091  {
3092  loc_grid.get(i).findNeighbours();
3093  }
3094  }
3095 
3100  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 >
3101  void conv_cross2(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
3102  {
3103  for (int i = 0 ; i < loc_grid.size() ; i++)
3104  {
3105  Box<dim,long int> inte;
3106 
3107  Box<dim,long int> base;
3108  for (int j = 0 ; j < dim ; j++)
3109  {
3110  base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3111  base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3112  }
3113 
3114  Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3115 
3116  bool overlap = dom.Intersect(base,inte);
3117 
3118  if (overlap == true)
3119  {
3120  loc_grid.get(i).template conv_cross2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3121  }
3122  }
3123  }
3124 
3136  bool write(std::string output, size_t opt = VTK_WRITER | FORMAT_BINARY )
3137  {
3138 #ifdef SE_CLASS2
3139  check_valid(this,8);
3140 #endif
3141 
3142  file_type ft = file_type::ASCII;
3143 
3144  if (opt & FORMAT_BINARY)
3145  {ft = file_type::BINARY;}
3146 
3147  // Create a writer and write
3149  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3150  {
3151  Point<dim,St> offset = getOffset(i);
3152 
3153  if (opt & PRINT_GHOST)
3154  {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).GDbox);}
3155  else
3156  {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);}
3157  }
3158  vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk", prp_names, "grids", ft);
3159 
3160  return true;
3161  }
3162 
3168  bool write_debug(std::string output)
3169  {
3170  for (int i = 0 ; i < getN_loc_grid() ; i++)
3171  {
3172  Point<dim,St> sp;
3173  Point<dim,St> offset;
3174 
3175  for (int j = 0 ; j < dim ; j++)
3176  {sp.get(j) = this->spacing(j);}
3177 
3178  offset = gdb_ext.get(i).origin;
3179 
3180  get_loc_grid(i).write_debug(output + "_" + std::to_string(i) + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk",sp,offset);
3181  }
3182 
3183  return true;
3184  }
3185 
3198  bool write_frame(std::string output, size_t i, size_t opt = VTK_WRITER | FORMAT_ASCII)
3199  {
3200 #ifdef SE_CLASS2
3201  check_valid(this,8);
3202 #endif
3203  file_type ft = file_type::ASCII;
3204 
3205  if (opt & FORMAT_BINARY)
3206  ft = file_type::BINARY;
3207 
3208  // Create a writer and write
3210  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3211  {
3212  Point<dim,St> offset = getOffset(i);
3213  vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);
3214  }
3215  vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(i) + ".vtk",prp_names,"grids",ft);
3216 
3217  return true;
3218  }
3219 
3220 
3221 
3230  {
3231  return loc_grid.get(i);
3232  }
3233 
3241  const device_grid & get_loc_grid(size_t i) const
3242  {
3243  return loc_grid.get(i);
3244  }
3245 
3254  {
3255  return grid_key_dx_iterator_sub<dim,no_stencil>(loc_grid.get(i).getGrid(),
3256  gdb_ext.get(i).Dbox.getKP1(),
3257  gdb_ext.get(i).Dbox.getKP2());
3258  }
3259 
3267  template<unsigned int Np>
3268  grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>
3269  get_loc_grid_iterator_stencil(size_t i,const grid_key_dx<dim> (& stencil_pnt)[Np])
3270  {
3271  return grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>(loc_grid.get(i).getGrid(),
3272  gdb_ext.get(i).Dbox.getKP1(),
3273  gdb_ext.get(i).Dbox.getKP2(),
3274  stencil_pnt);
3275  }
3276 
3282  size_t getN_loc_grid() const
3283  {
3284  return loc_grid.size();
3285  }
3286 
3291  void debugPrint()
3292  {
3293  size_t tot_volume = 0;
3294 
3295  std::cout << "-------- External Ghost boxes ---------- " << std::endl;
3296 
3297  for (size_t i = 0 ; i < eg_box.size() ; i++)
3298  {
3299  std::cout << "Processor: " << eg_box.get(i).prc << " Boxes:" << std::endl;
3300 
3301  for (size_t j = 0; j < eg_box.get(i).bid.size() ; j++)
3302  {
3303  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;
3304  tot_volume += eg_box.get(i).bid.get(j).g_e_box.getVolumeKey();
3305  }
3306  }
3307 
3308  std::cout << "TOT volume external ghost " << tot_volume << std::endl;
3309 
3310  std::cout << "-------- Internal Ghost boxes ---------- " << std::endl;
3311 
3312  tot_volume = 0;
3313  for (size_t i = 0 ; i < ig_box.size() ; i++)
3314  {
3315  std::cout << "Processor: " << ig_box.get(i).prc << " Boxes:" << std::endl;
3316 
3317  for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
3318  {
3319  std::cout << " Box: " << ig_box.get(i).bid.get(j).box.toString() << " Id: " << ig_box.get(i).bid.get(j).g_id << std::endl;
3320  tot_volume += ig_box.get(i).bid.get(j).box.getVolumeKey();
3321  }
3322  }
3323 
3324  std::cout << "TOT volume internal ghost " << tot_volume << std::endl;
3325  }
3326 
3335  {
3336  prp_names = names;
3337  }
3338 
3347  {
3348  return prp_names;
3349  }
3350 
3357  void clear()
3358  {
3359  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3360  {loc_grid.get(i).clear();}
3361  }
3362 
3369  void construct_link(self & grid_up, self & grid_dw)
3370  {
3371  for (int i = 0 ; i < loc_grid.size() ; i++)
3372  {
3373  loc_grid.get(i).construct_link(grid_up.get_loc_grid(i),grid_dw.get_loc_grid(i),v_cl.getGpuContext());
3374  }
3375  }
3376 
3383  void construct_link_dw(self & grid_dw, openfpm::vector<offset_mv<dim>> & mvof)
3384  {
3385  for (int i = 0 ; i < loc_grid.size() ; i++)
3386  {
3387  Point<dim,int> p_dw;
3388  for(int j = 0 ; j < dim ; j++)
3389  {p_dw.get(j) = mvof.get(i).dw.get(j);}
3390 
3391  loc_grid.get(i).construct_link_dw(grid_dw.get_loc_grid(i),gdb_ext.get(i).Dbox,p_dw,v_cl.getGpuContext());
3392  }
3393  }
3394 
3401  void construct_link_up(self & grid_up, openfpm::vector<offset_mv<dim>> & mvof)
3402  {
3403  for (int i = 0 ; i < loc_grid.size() ; i++)
3404  {
3405  Point<dim,int> p_up;
3406  for(int j = 0 ; j < dim ; j++)
3407  {p_up.get(j) = mvof.get(i).up.get(j);}
3408 
3409  loc_grid.get(i).construct_link_up(grid_up.get_loc_grid(i),gdb_ext.get(i).Dbox,p_up,v_cl.getGpuContext());
3410  }
3411  }
3412 
3419  template<typename stencil_type>
3421  {
3422  for (int i = 0 ; i < loc_grid.size() ; i++)
3423  {
3424  // we limit to the domain subset for tagging
3425 
3426  Box_check<dim,unsigned int> chk(gdb_ext.get(i).Dbox);
3427 
3428 
3429  loc_grid.get(i).template tagBoundaries<stencil_type>(v_cl.getGpuContext(),chk);
3430  }
3431  }
3432 
3436  void map(size_t opt = 0)
3437  {
3438  // Save the background values
3439  T bv;
3440 
3441  copy_aggregate_dual<decltype(loc_grid.get(0).getBackgroundValue()),
3442  T> ca(loc_grid.get(0).getBackgroundValue(),bv);
3443 
3444  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(ca);
3445 
3446  if (!(opt & NO_GDB_EXT_SWITCH))
3447  {
3448  gdb_ext_old = gdb_ext;
3450 
3452  }
3453 
3455 
3456 
3457  typedef typename to_int_sequence<0,T::max_prop-1>::type result;
3458 
3460 
3461  loc_grid_old.clear();
3462  loc_grid_old.shrink_to_fit();
3463  gdb_ext_old.clear();
3464 
3465  // reset ghost structure to recalculate
3466  reset_ghost_structures();
3467 
3468  // Reset the background values
3469  setBackgroundValue(bv);
3470  }
3471 
3477  inline void save(const std::string & filename) const
3478  {
3480 
3481  h5s.save(filename,loc_grid,gdb_ext);
3482  }
3483 
3489  inline void load(const std::string & filename)
3490  {
3492 
3493  h5l.load<device_grid>(filename,loc_grid_old,gdb_ext_old);
3494 
3495  if (v_cl.size() != 1)
3496  {
3497  // move information from host to device
3498  for (int i = 0 ; i < loc_grid_old.size() ; i++)
3499  {loc_grid_old.get(i).template hostToDevice<0>();}
3500  // Map the distributed grid
3501  size_t opt_ = NO_GDB_EXT_SWITCH;
3502  if (std::is_same<Memory,CudaMemory>::value == true)
3503  {opt_ |= RUN_ON_DEVICE;}
3504  map(opt_);
3505  }
3506  else
3507  {
3508  device_grid_copy<device_grid::isCompressed()>::pre_load(gdb_ext_old,loc_grid_old,gdb_ext,loc_grid);
3509  for (int i = 0 ; i < gdb_ext_old.size() ; i++)
3510  {
3511  auto & lg = loc_grid_old.get(i);
3512  auto it_src = lg.getIterator(gdb_ext_old.get(i).Dbox.getKP1(),gdb_ext_old.get(i).Dbox.getKP2());
3513  auto & dg = loc_grid.get(0);
3514  grid_key_dx<dim> kp1 = gdb_ext.get(0).Dbox.getKP1();
3515 
3516  grid_key_dx<dim> orig;
3517  for (int j = 0 ; j < dim ; j++)
3518  {
3519  orig.set_d(j,gdb_ext_old.get(i).origin.get(j));
3520  }
3521 
3522  while (it_src.isNext())
3523  {
3524  auto key = it_src.get();
3525  grid_key_dx<dim> key_dst;
3526 
3527  for (int j = 0 ; j < dim ; j++)
3528  {key_dst.set_d(j,key.get(j) + orig.get(j) + kp1.get(j));}
3529 
3530  device_grid_copy<device_grid::isCompressed()>::assign(key,key_dst,dg,lg);
3531 
3532  ++it_src;
3533  }
3534 
3535  dg.template hostToDevice<0>();
3536  }
3537  }
3538  }
3539 
3545  template <typename stencil = no_stencil>
3547  {
3549  }
3550 
3557  {
3558  return this->loc_ig_box;
3559  }
3560 
3567  {
3568  return this->ig_box;
3569  }
3570 
3571  void print_stats()
3572  {
3573  std::cout << "-- REPORT --" << std::endl;
3574 #ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3575  std::cout << "Processor: " << v_cl.rank() << " Time spent in packing data: " << tot_pack << std::endl;
3576  std::cout << "Processor: " << v_cl.rank() << " Time spent in sending and receving data: " << tot_sendrecv << std::endl;
3577  std::cout << "Processor: " << v_cl.rank() << " Time spent in merging: " << tot_merge << std::endl;
3578  std::cout << "Processor: " << v_cl.rank() << " Time spent in local merging: " << tot_loc_merge << std::endl;
3579 #else
3580 
3581  std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3582 
3583 #endif
3584  }
3585 
3586  void clear_stats()
3587  {
3588 #ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3589  tot_pack = 0;
3590  tot_sendrecv = 0;
3591  tot_merge = 0;
3592 #else
3593 
3594  std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3595 
3596 #endif
3597  }
3598 
3599 #ifdef __NVCC__
3600 
3606  void setNumberOfInsertPerThread(size_t n_ins)
3607  {
3608  gpu_n_insert_thread = n_ins;
3609  }
3610 
3611  template<typename func_t,typename it_t, typename ... args_t>
3612  void iterateGridGPU(it_t & it, args_t ... args)
3613  {
3614  // setGPUInsertBuffer must be called in anycase even with 0 points to insert
3615  // the loop "it.isNextGrid()" does not guarantee to call it for all local grids
3616  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3617  {loc_grid.get(i).setGPUInsertBuffer(0ul,1ul);}
3618 
3619  while(it.isNextGrid())
3620  {
3621  Box<dim,size_t> b = it.getGridBox();
3622 
3623  size_t i = it.getGridId();
3624 
3625  auto ite = loc_grid.get(i).getGridGPUIterator(b.getKP1int(),b.getKP2int());
3626 
3627  loc_grid.get(i).setGPUInsertBuffer(ite.nblocks(),ite.nthrs());
3628  loc_grid.get(i).initializeGPUInsertBuffer();
3629 
3630  ite_gpu_dist<dim> itd = ite;
3631 
3632  for (int j = 0 ; j < dim ; j++)
3633  {
3634  itd.origin.set_d(j,gdb_ext.get(i).origin.get(j));
3635  itd.start_base.set_d(j,0);
3636  }
3637 
3638  CUDA_LAUNCH((grid_apply_functor),ite,loc_grid.get(i).toKernel(),itd,func_t(),args...);
3639 
3640  it.nextGrid();
3641  }
3642  }
3643 
3649  void removePoints(Box<dim,size_t> & box)
3650  {
3651  Box<dim,long int> box_i = box;
3652 
3653  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3654  {
3655  Box<dim,long int> bx = gdb_ext.get(i).Dbox + gdb_ext.get(i).origin;
3656 
3657  Box<dim,long int> bout;
3658  bool inte = bx.Intersect(box,bout);
3659  bout -= gdb_ext.get(i).origin;
3660 
3661  if (inte == true)
3662  {
3663  loc_grid.get(i).copyRemoveReset();
3664  loc_grid.get(i).remove(bout);
3665  loc_grid.get(i).removePoints(v_cl.getGpuContext());
3666  }
3667  }
3668  }
3669 
3673  template<unsigned int ... prp> void deviceToHost()
3674  {
3675  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3676  {
3677  loc_grid.get(i).template deviceToHost<prp ...>();
3678  }
3679  }
3680 
3684  template<unsigned int ... prp> void hostToDevice()
3685  {
3686  for (size_t i = 0 ; i < loc_grid.size() ; i++)
3687  {
3688  loc_grid.get(i).template hostToDevice<prp ...>();
3689  }
3690  }
3691 
3692 #endif
3693 
3694 
3696  //\cond
3698  //\endcond
3699 };
3700 
3701 
3702 template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St> >
3704 
3705 template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3707 
3708 template<unsigned int dim, typename St, typename T, typename devg, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3710 
3711 #ifdef __NVCC__
3712 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3714 
3715 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3717 
3718 template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3720 #endif
3721 
3722 #endif
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:707
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:555
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:94
void zero()
Set p1 and p2 to 0.
Definition: Box.hpp:982
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:566
grid_key_dx< dim > getKP1() const
Get the point p1 as grid_key_dx.
Definition: Box.hpp:655
void magnify_fix_P1(T mg)
Magnify the box by a factor keeping fix the point P1.
Definition: Box.hpp:906
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:822
grid_key_dx< dim > getKP2() const
Get the point p12 as grid_key_dx.
Definition: Box.hpp:668
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:1186
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:543
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:532
This class define the domain decomposition interface.
bool isInvalidGhost()
check if the Ghost is valid
Definition: Ghost.hpp:106
This class allocate, and destroy CPU memory.
Definition: HeapMemory.hpp:40
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
size_t size()
Get the total number of processors.
size_t getProcessUnitID()
Get the process unit id.
gpu::ofp_context_t & getGpuContext(bool iw=true)
If nvidia cuda is activated return a gpu context.
size_t getProcessingUnits()
Get the total number of processors.
bool recv(size_t proc, size_t tag, void *v, size_t sz)
Recv data from a processor.
bool send(size_t proc, size_t tag, const void *mem, size_t sz)
Send data to a processor.
Implementation of VCluster class.
Definition: VCluster.hpp:59
bool SGather(T &send, S &recv, size_t root)
Semantic Gather, gather the data from all processors into one node.
Definition: VCluster.hpp:455
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:803
Distributed linearized key.
This class is an helper for the communication of grid_dist_id.
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< grid_cpu< dim, T > > &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 ghost_put_(CartDecomposition< dim, St > &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< grid_cpu< dim, T > > &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.
Given the decomposition it create an iterator.
Given the decomposition it create an iterator.
This is a distributed grid.
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.
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.
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 conv_cross2(grid_key_dx< 3 > start, grid_key_dx< 3 > stop, lambda_f func, ArgsT ... args)
apply a convolution using the stencil N
Point< dim, St > getPos(const grid_dist_key_dx< dim, bg_key > &v1)
Get the reference of the selected element.
openfpm::vector< std::string > prp_names
properties names
void setBackgroundValue(T &bv)
set the background value
grid_sm< dim, void > ginfo_v
Grid informations object without type.
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
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
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.
const device_grid & get_loc_grid(size_t i) const
Get the i sub-domain grid.
T value_type
value_type
bool init_e_g_box
Flag that indicate if the external ghost box has been initialized.
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.
grid_sm< dim, T > ginfo
Grid informations object.
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
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.
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
void removeUnusedBuffers()
Eliminate many internal temporary buffer you can use this between flushes if you get some out of memo...
openfpm::vector< ip_box_grid< dim > > ig_box
Internal ghost boxes in grid units.
const grid_sm< dim, T > & getGridInfo() const
Get an object containing the grid informations.
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.
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, St > &g, size_t opt=0)
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.
void map(size_t opt=0)
It move all the grid parts that do not belong to the local processor to the respective processor.
const CellDecomposer_sm< dim, St, shift< dim, St > > & getCellDecomposer() const
Return the cell decomposer.
grid_dist_id(Decomposition &&dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
grid_dist_id(const Decomposition &dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
Memory memory_type
Type of Memory.
device_grid d_grid
Which kind of grid the structure store.
openfpm::vector< size_t > gdb_ext_markers
Box< dim, St > domain
Domain.
size_t getLocalDomainSize() const
Get the total number of grid points for the calling processor.
openfpm::vector< e_lbox_grid< dim > > loc_eg_box
Local external ghost boxes in grid units.
const openfpm::vector< std::string > & getPropNames()
Set the properties names.
void flush_remove()
remove an element in the grid
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.
bool init_i_g_box
Flag that indicate if the internal ghost box has been initialized.
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
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
void ghost_get(size_t opt=0)
It synchronize the ghost parts.
void setBackgroundValue(const typename boost::mpl::at< typename T::type, boost::mpl::int_< p >>::type &bv)
set the background value
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 >())
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
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)
Decomposition dec
Space Decomposition.
openfpm::vector< e_box_multi< dim > > eb_gid_list
device_grid device_grid_type
Type of device 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.
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.
void create_ig_box()
Create per-processor internal ghost boxes list in grid units and g_id_to_external_ghost_box.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext
Extension of each grid: Domain and ghost + domain.
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.
Ghost< dim, long int > ghost_int
Ghost expansion.
openfpm::vector< device_grid > & getLocalGrid()
Get the local grid.
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 size(size_t i) const
Return the total number of points in the grid.
auto getProp(const grid_dist_key_dx< dim, bgkey > &v1) const -> decltype(this->template get< p >(v1))
Get the reference of the selected element.
size_t g_sz[dim]
Size of the grid on each dimension.
grid_key_dx_iterator_sub< dim, no_stencil > get_loc_grid_iterator(size_t i)
Get the i sub-domain grid.
const Box< dim, St > getDomain() const
Get the domain where the grid is defined.
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
void clear()
It delete all the points.
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)
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(const grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g)
Copy constructor.
grid_dist_id_iterator_dec< Decomposition, true > getGridGhostIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
void tagBoundaries()
construct link between current and the level up
Point< dim, St > getSpacing()
Get the spacing on each dimension.
bool existPoint(const grid_dist_key_dx< dim, bg_key > &v1) const
Check if the point exist.
const openfpm::vector< GBoxes< device_grid::dims > > & getLocalGridsInfo() const
It return the informations about the local grids.
size_t size() const
Return the total number of points in the grid.
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.
grid_dist_id_iterator_dec< Decomposition > getGridIterator()
~grid_dist_id()
Destructor.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition using a resolution function.
auto getProp(const grid_dist_key_dx< dim, bgkey > &v1) -> decltype(this->template get< p >(v1))
Get the reference of the selected element.
St stype
Type of space.
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.
St spacing(size_t i) const
Get the spacing of the grid in direction i.
bool write(std::string output, size_t opt=VTK_WRITER|FORMAT_BINARY)
Write the distributed grid information.
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.
bool use_bx_def
Indicate if we have to use bx_def to define the grid.
Vcluster & v_cl
Communicator class.
openfpm::vector< i_lbox_grid< dim > > loc_ig_box
Local internal ghost boxes in grid units.
void construct_link_up(self &grid_up, openfpm::vector< offset_mv< dim >> &mvof)
construct link between current and the level up
void ghost_put()
It synchronize the ghost parts.
const openfpm::vector< i_lbox_grid< dim > > & get_loc_ig_box()
Get the internal local ghost box.
size_t getLocalDomainWithGhostSize() const
Get the total number of grid points with ghost for the calling processor.
grid_dist_id(Decomposition &&dec, const size_t(&g_sz)[dim], const Ghost< dim, St > &ghost)
void create_local_eg_box()
Create per-processor external ghost boxes list in grid units.
Ghost< dim, St > ghost
Ghost expansion.
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.
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.
bool init_local_i_g_box
Indicate if the local internal ghost box has been initialized.
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
openfpm::vector< device_grid > loc_grid_old
Old local grids.
void save(const std::string &filename) const
Save the grid state on HDF5.
Point< dim, St > getOffset(size_t i)
Get the point where it start the origin of the grid of the sub-domain i.
openfpm::vector< std::unordered_map< size_t, size_t > > g_id_to_internal_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
grid_dist_id(const Decomposition2 &dec, const size_t(&g_sz)[dim], const Ghost< dim, St > &ghost)
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.
Vcluster & getVC()
Get the Virtual Cluster machine.
openfpm::vector< device_grid > loc_grid
Local grids.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_global
Global gdb_ext.
auto insertFlush(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).insertFlush(v1.getKey()))
insert an element in the grid
openfpm::vector< size_t > recv_sz
Receiving size.
const Decomposition & getDecomposition() const
Get the object that store the information about the decomposition.
void check_domain(const Box< dim, St > &dom)
Check the domain is valid.
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)
void remove_no_flush(const grid_dist_key_dx< dim, bg_key > &v1)
remove an element in the grid
bool isInside(const grid_key_dx< dim > &gk) const
Check that the global grid key is inside the grid domain.
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)
void remove(const grid_dist_key_dx< dim, bg_key > &v1)
remove an element in the grid
void load(const std::string &filename)
Reload the grid from HDF5 file.
size_t getN_loc_grid() const
Return the number of local grid.
void create_eg_box()
Create per-processor internal ghost box list in grid units.
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.
static const unsigned int dims
Number of dimensions.
bool init_fix_ie_g_box
Flag that indicate if the internal and external ghost box has been fixed.
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...
void construct_link(self &grid_up, self &grid_dw)
construct link between levels
void construct_link_dw(self &grid_dw, openfpm::vector< offset_mv< dim >> &mvof)
construct link between current and the level down
openfpm::vector< ep_box_grid< dim > > eg_box
External ghost boxes in grid units.
void debugPrint()
It print the internal ghost boxes and external ghost boxes in global unit.
void create_local_ig_box()
Create local internal ghost box in grid units.
const openfpm::vector< i_lbox_grid< dim > > & get_ig_box()
Get the internal ghost box.
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 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.
const grid_sm< dim, void > & getGridInfoVoid() const
Get an object containing the grid informations without type.
grid_dist_id(const Decomposition2 &dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
Decomposition decomposition
Decomposition used.
void InitializeStructures(const size_t(&g_sz)[dim])
Initialize the grid.
std::unordered_map< size_t, size_t > g_id_to_external_ghost_box
CellDecomposer_sm< dim, St, shift< dim, St > > cd_sm
Structure that divide the space into cells.
void check_size(const size_t(&g_sz)[dim])
Check the grid has a valid size.
void conv3_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 is_staggered() const
Indicate that this grid is not staggered.
device_grid & get_loc_grid(size_t i)
Get the i sub-domain grid.
openfpm::vector< Box< dim, long int > > bx_def
Set of boxes that define where the grid is defined.
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
bool write_debug(std::string output)
Write all grids indigually.
openfpm::vector< HeapMemory > recv_mem_gg
Receiving buffer for particles ghost get.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_old
Extension of each old grid (old): Domain and ghost + domain.
void InitializeCellDecomposer(const size_t(&g_sz)[dim], const size_t(&bc)[dim])
Initialize the Cell decomposer of the grid.
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
size_t gpu_n_insert_thread
number of insert each GPU thread does
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
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
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< 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.
bool init_local_e_g_box
Indicate if the local external ghost box has been initialized.
void getGlobalGridsInfo(openfpm::vector< GBoxes< device_grid::dims >> &gdb_ext_global) const
It gathers the information about local grids for all of the processors.
bool write_frame(std::string output, size_t i, size_t opt=VTK_WRITER|FORMAT_ASCII)
Write the distributed grid information.
Distributed grid iterator.
Distributed grid iterator.
Grid key for a distributed grid.
base_key & getKeyRef()
Get the reference key.
size_t getSub() const
Get the local grid.
base_key getKey() const
Get the key.
Distributed linearized key.
Declaration grid_key_dx_iterator_sub.
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:19
void one()
Set to one the key.
Definition: grid_key.hpp:179
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
Declaration grid_sm.
Definition: grid_sm.hpp:167
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:326
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:760
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:657
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:204
size_t size()
Stub size.
Definition: map_vector.hpp:212
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
Internal ghost box sent to construct external ghost box into the other processors.
size_t g_id
Global id of the internal ghost box.
comb< dim > cmb
In which sector live the box.
size_t r_sub
from which sub-domain this internal ghost box is generated (or with which sub-domain is overlapping)
Box< dim, size_t > bx
Box in global unit.
This structure store the Box that define the domain inside the Ghost + domain box.
Definition: GBoxes.hpp:40
Box< dim, long int > GDbox
Ghost + Domain ghost.
Definition: GBoxes.hpp:42
size_t k
Definition: GBoxes.hpp:50
Point< dim, long int > origin
origin of GDbox in global grid coordinates
Definition: GBoxes.hpp:46
Box< dim, long int > Dbox
Domain box.
Definition: GBoxes.hpp:44
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:35
void sign_flip()
Flip the sign of the combination.
Definition: comb.hpp:124
signed char c[dim]
Array that store the combination.
Definition: comb.hpp:37
Structure to copy aggregates.
const e_src & block_data_src
encapsulated source object
__device__ __host__ copy_all_prop_sparse(const e_src &block_data_src, e_dst &block_data_dst, indexT local_id)
constructor
It store the information about the external ghost box.
size_t sub
sub_id in which sub-domain this box live
::Box< dim, long int > g_e_box
Box defining the external ghost box in global coordinates.
size_t g_id
Id.
::Box< dim, long int > l_e_box
Box defining the external ghost box in local coordinates for gdb_ext.
comb< dim > cmb
Sector position of the external ghost.
it store a box, its unique id and the sub-domain from where it come from
size_t sub
sub
comb< dim > cmb
Sector where it live the linked external ghost box.
::Box< dim, long int > box
Box.
size_t g_id
id
size_t r_sub
r_sub id of the sub-domain in the sent list
Definition: ids.hpp:169
It contain the offset necessary to move to coarser and finer level grids.
Point< dim, long int > up
offset to move up on an upper grid (coarse)
Point< dim, long int > dw
offset to move on the lower grid (finer)
Boundary conditions.
Definition: common.hpp:22
this class is a functor for "for_each" algorithm
Definition: grid_common.hpp:23
Structure for stencil iterator.