OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
grid_dist_id.hpp
1#ifndef COM_UNIT_HPP
2#define COM_UNIT_HPP
3
4#include <vector>
5#include <unordered_map>
6#include "Grid/map_grid.hpp"
7#include "VCluster/VCluster.hpp"
8#include "Space/SpaceBox.hpp"
9#include "util/mathutil.hpp"
10#include "VTKWriter/VTKWriter.hpp"
11#ifdef __NVCC__
12#include "SparseGridGpu/SparseGridGpu.hpp"
13#endif
14#include "Iterators/grid_dist_id_iterator_dec.hpp"
15#include "Iterators/grid_dist_id_iterator.hpp"
16#include "Iterators/grid_dist_id_iterator_sub.hpp"
17#include "grid_dist_key.hpp"
18#include "NN/CellList/CellDecomposer.hpp"
19#include "util/object_util.hpp"
20#include "memory/ExtPreAlloc.hpp"
21#include "Packer_Unpacker/Packer.hpp"
22#include "Packer_Unpacker/Unpacker.hpp"
23#include "Decomposition/CartDecomposition.hpp"
24#include "data_type/aggregate.hpp"
25#include "hdf5.h"
26#include "grid_dist_id_comm.hpp"
27#include "HDF5_wr/HDF5_wr.hpp"
28#include "SparseGrid/SparseGrid.hpp"
29#include "lib/pdata.hpp"
30#ifdef __NVCC__
31#include "cuda/grid_dist_id_kernels.cuh"
32#include "Grid/cuda/grid_dist_id_iterator_gpu.cuh"
33#endif
34
38template<unsigned int dim>
40{
43
46};
47
49template<unsigned int dim>
50struct Box_fix
51{
57 size_t g_id;
59 size_t r_sub;
60};
61
62#define NO_GDB_EXT_SWITCH 0x1000
63
64template<bool is_sparse>
66{
67 template<typename key_type1, typename key_type2, typename spg_type, typename lg_type>
68 static void assign(key_type1 & key, key_type2 & key_dst, spg_type & dg, lg_type & lg)
69 {
70 dg.insert_o(key_dst) = lg.get_o(key);
71 }
72
73 template<typename gdb_ext_type, typename loc_grid_type>
74 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)
75 {
76 }
77};
78
79template<typename e_src, typename e_dst, typename indexT>
81{
83 const e_src & block_data_src;
84 e_dst & block_data_dst;
85
86 indexT local_id;
87
94 __device__ __host__ inline copy_all_prop_sparse(const e_src & block_data_src, e_dst & block_data_dst, indexT local_id)
95 :block_data_src(block_data_src),block_data_dst(block_data_dst),local_id(local_id)
96 {
97 };
98
99 template<typename T>
100 __device__ __host__ inline void operator()(T& t) const
101 {
102 block_data_dst.template get<T::value>()[local_id] = block_data_src.template get<T::value>();
103 }
104};
105
106template<typename T>
108{};
109
110template<int ... prp>
112{
113 template<typename this_type, typename dec_type, typename cd_sm_type, typename loc_grid_type, typename gdb_ext_type>
114 static void call(this_type * this_,
115 dec_type & dec,
116 cd_sm_type & cd_sm,
117 loc_grid_type & loc_grid,
118 loc_grid_type & loc_grid_old,
119 gdb_ext_type & gdb_ext,
120 gdb_ext_type & gdb_ext_old,
121 gdb_ext_type & gdb_ext_global,
122 size_t opt)
123 {
124 this_->template map_<prp ...>(dec,cd_sm,loc_grid,loc_grid_old,gdb_ext,gdb_ext_old,gdb_ext_global,opt);
125 }
126};
127
128struct ids_pl
129{
130 size_t id;
131
132 bool operator<(const ids_pl & i) const
133 {
134 return id < i.id;
135 }
136
137 bool operator==(const ids_pl & i) const
138 {
139 return id == i.id;
140 }
141};
142
143template<>
145{
146 template<typename key_type1, typename key_type2, typename spg_type, typename lg_type>
147 static void assign(key_type1 & key, key_type2 & key_dst, spg_type & dg, lg_type & lg)
148 {
149 typename spg_type::indexT_ local_id;
150 auto block_data_dst = dg.insertBlockFlush(key_dst, local_id);
151 auto block_data_src = lg.get_o(key);
152
153 copy_all_prop_sparse<decltype(block_data_src),decltype(block_data_dst),decltype(local_id)> cp(block_data_src, block_data_dst, local_id);
154
155 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,decltype(block_data_dst)::max_prop> >(cp);
156 }
157
158
159
160 template<typename gdb_ext_type, typename loc_grid_type>
161 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)
162 {
163 auto & dg = loc_grid.get(0);
164 auto dlin = dg.getGrid();
165 typedef typename std::remove_reference<decltype(dg)>::type sparse_grid_type;
166
169
170 size_t sz[sparse_grid_type::dims];
171
172 for (int i = 0 ; i < sparse_grid_type::dims ; i++)
173 {sz[i] = 2;}
174
176
178 while(it.isNext())
179 {
180 auto key = it.get();
181
183 for (int i = 0 ; i < sparse_grid_type::dims ; i++)
184 {
185 k.set_d(i,key.get(i)*dlin.getBlockEgdeSize());
186 }
187
188 gg.add(k);
189 ++it;
190 }
191
192
193 for (int i = 0 ; i < gdb_ext_old.size() ; i++)
194 {
195
196 auto & lg = loc_grid_old.get(i);
197 auto & indexBuffer = lg.private_get_index_array();
198 auto & dg = loc_grid.get(0);
199
200 auto slin = loc_grid_old.get(i).getGrid();
201
202 grid_key_dx<sparse_grid_type::dims> kp1 = gdb_ext.get(0).Dbox.getKP1();
203
205 for (int j = 0 ; j < sparse_grid_type::dims ; j++)
206 {
207 orig.set_d(j,gdb_ext_old.get(i).origin.get(j));
208 }
209
210 for (int i = 0; i < indexBuffer.size() ; i++)
211 {
212 for (int ex = 0; ex < gg.size() ; ex++) {
213 auto key = slin.InvLinId(indexBuffer.template get<0>(i),0);
215
216 for (int j = 0 ; j < sparse_grid_type::dims ; j++)
217 {key_dst.set_d(j,key.get(j) + orig.get(j) + kp1.get(j) + gg.get(ex).get(j));}
218
219 typename sparse_grid_type::indexT_ bid;
220 int lid;
221
222 dlin.LinId(key_dst,bid,lid);
223
224 ids.add();
225 ids.last().id = bid;
226 }
227 }
228 }
229
230 ids.sort();
231 ids.unique();
232
233 auto & indexBuffer = dg.private_get_index_array();
234 auto & dataBuffer = dg.private_get_data_array();
235 indexBuffer.reserve(ids.size()+8);
236 dataBuffer.reserve(ids.size()+8);
237 for (int i = 0 ; i < ids.size() ; i++)
238 {
239 auto & dg = loc_grid.get(0);
240 dg.insertBlockFlush(ids.get(i).id);
241 }
242 }
243};
244
271template<unsigned int dim,
272 typename St,
273 typename T,
275 typename Memory=HeapMemory ,
277class grid_dist_id : public grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>
278{
280
283
286
289
292
295
298
309
312
315
318
320 size_t g_sz[dim];
321
323 CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
324
327
330
333
336 std::unordered_map<size_t,size_t> g_id_to_external_ghost_box;
337
407
411
414
417
420
423
426
428 bool use_bx_def = false;
429
431 bool init_local_i_g_box = false;
432
434 bool init_local_e_g_box = false;
435
437 bool init_e_g_box = false;
438
440 bool init_i_g_box = false;
441
443 bool init_fix_ie_g_box = false;
444
447
450
453
456
458 size_t v_sub_unit_factor = 64;
459
471 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)
472 {
474
475 g->recv_sz.resize(g->dec.getNNProcessors());
476 g->recv_mem_gg.resize(g->dec.getNNProcessors());
477
478 // Get the local processor id
479 size_t lc_id = g->dec.ProctoID(i);
480
481 // resize the receive buffer
482 g->recv_mem_gg.get(lc_id).resize(msg_i);
483 g->recv_sz.get(lc_id) = msg_i;
484
485 return g->recv_mem_gg.get(lc_id).getPointer();
486 }
487
500 void set_for_adjustment(size_t sub_id,
501 const Box<dim,St> & sub_domain_other,
502 const comb<dim> & cmb,
505 {
506 if (g.isInvalidGhost() == true || use_bx_def == true)
507 {return;}
508
509 Box<dim,long int> sub_domain;
510
511 if (use_bx_def == false)
512 {
513 sub_domain = gdb_ext.get(sub_id).Dbox;
514 sub_domain += gdb_ext.get(sub_id).origin;
515 }
516
517 // Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
518 Box<dim,long int> sub_domain_other_exp = cd_sm.convertDomainSpaceIntoGridUnits(sub_domain_other,dec.periodicity());
519
520 // translate sub_domain_other based on cmb
521 for (size_t i = 0 ; i < dim ; i++)
522 {
523 if (cmb.c[i] == 1)
524 {
525 sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) - ginfo.size(i));
526 sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) - ginfo.size(i));
527 }
528 else if (cmb.c[i] == -1)
529 {
530 sub_domain_other_exp.setLow(i,sub_domain_other_exp.getLow(i) + ginfo.size(i));
531 sub_domain_other_exp.setHigh(i,sub_domain_other_exp.getHigh(i) + ginfo.size(i));
532 }
533 }
534
535 sub_domain_other_exp.enlarge(g);
536 if (sub_domain_other_exp.Intersect(sub_domain,ib) == false)
537 {
538 for (size_t i = 0 ; i < dim ; i++)
539 {ib.setHigh(i,ib.getLow(i) - 1);}
540 }
541 }
542
543
544
549 {
550 // temporal vector used for computation
552
553 if (init_i_g_box == true) return;
554
555 // Get the grid info
556 auto g = cd_sm.getGrid();
557
558 g_id_to_internal_ghost_box.resize(dec.getNNProcessors());
559
560 // Get the number of near processors
561 for (size_t i = 0 ; i < dec.getNNProcessors() ; i++)
562 {
563 ig_box.add();
564 auto&& pib = ig_box.last();
565
566 pib.prc = dec.IDtoProc(i);
567 for (size_t j = 0 ; j < dec.getProcessorNIGhost(i) ; j++)
568 {
569 // Get the internal ghost boxes and transform into grid units
570 ::Box<dim,St> ib_dom = dec.getProcessorIGhostBox(i,j);
571 ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
572
573 size_t sub_id = dec.getProcessorIGhostSub(i,j);
574 size_t r_sub = dec.getProcessorIGhostSSub(i,j);
575
576 auto & n_box = dec.getNearSubdomains(dec.IDtoProc(i));
577
578 set_for_adjustment(sub_id,
579 n_box.get(r_sub),dec.getProcessorIGhostPos(i,j),
580 ib,ghost_int);
581
582 // Here we intersect the internal ghost box with the definition boxes
583 // this operation make sense when the grid is not defined in the full
584 // domain and we have to intersect the internal ghost box with all the box
585 // that define where the grid is defined
586 bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
587
588 for (size_t k = 0 ; k < ibv.size() ; k++)
589 {
590 // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
591 if (ibv.get(k).bx.isValid() == false)
592 {continue;}
593
594 // save the box and the sub-domain id (it is calculated as the linearization of P1)
595 ::Box<dim,size_t> cvt = ibv.get(k).bx;
596
597 i_box_id<dim> bid_t;
598 bid_t.box = cvt;
599 bid_t.g_id = dec.getProcessorIGhostId(i,j) | (k) << 52;
600
601 bid_t.sub = convert_to_gdb_ext(dec.getProcessorIGhostSub(i,j),
602 ibv.get(k).id,
603 gdb_ext,
605
606 bid_t.cmb = dec.getProcessorIGhostPos(i,j);
607 bid_t.r_sub = dec.getProcessorIGhostSSub(i,j);
608 pib.bid.add(bid_t);
609
610 g_id_to_internal_ghost_box.get(i)[bid_t.g_id | (k) << 52 ] = pib.bid.size()-1;
611 }
612 }
613 }
614
615 init_i_g_box = true;
616 }
617
618
623 {
624 // Get the grid info
625 auto g = cd_sm.getGrid();
626
627 if (init_e_g_box == true) return;
628
629 // Here we collect all the calculated internal ghost box in the sector different from 0 that this processor has
630
634 openfpm::vector<openfpm::vector<Box_fix<dim>>> box_int_send(dec.getNNProcessors());
636
637 for(size_t i = 0 ; i < dec.getNNProcessors() ; i++)
638 {
639 for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
640 {
641 box_int_send.get(i).add();
642 box_int_send.get(i).last().bx = ig_box.get(i).bid.get(j).box;
643 box_int_send.get(i).last().g_id = ig_box.get(i).bid.get(j).g_id;
644 box_int_send.get(i).last().r_sub = ig_box.get(i).bid.get(j).r_sub;
645 box_int_send.get(i).last().cmb = ig_box.get(i).bid.get(j).cmb;
646 }
647 prc.add(dec.IDtoProc(i));
648 }
649
650 v_cl.SSendRecv(box_int_send,box_int_recv,prc,prc_recv,sz_recv);
651
652 eg_box.resize(dec.getNNProcessors());
653
654 for (size_t i = 0 ; i < eg_box.size() ; i++)
655 {eg_box.get(i).prc = dec.IDtoProc(i);}
656
657 for (size_t i = 0 ; i < box_int_recv.size() ; i++)
658 {
659 size_t pib_cnt = 0;
660 size_t p_id = dec.ProctoID(prc_recv.get(i));
661 auto&& pib = eg_box.get(p_id);
662 pib.prc = prc_recv.get(i);
663
664 eg_box.get(p_id).recv_pnt = 0;
665 eg_box.get(p_id).n_r_box = box_int_recv.get(i).size();
666
667 // For each received internal ghost box
668 for (size_t j = 0 ; j < box_int_recv.get(i).size() ; j++)
669 {
670 size_t vol_recv = box_int_recv.get(i).get(j).bx.getVolumeKey();
671
672 eg_box.get(p_id).recv_pnt += vol_recv;
673 size_t send_list_id = box_int_recv.get(i).get(j).r_sub;
674
675 if (use_bx_def == true)
676 {
677 // First we understand if the internal ghost box sent intersect
678 // some local extended sub-domain.
679
680 // eb_gid_list, for an explanation check the declaration
681 eb_gid_list.add();
682 eb_gid_list.last().e_id = p_id;
683
684 // Now we have to check if a received external ghost box intersect one
685 // or more sub-grids
686 for (size_t k = 0 ; k < gdb_ext.size() ; k++)
687 {
688 Box<dim,long int> bx = gdb_ext.get(k).GDbox;
689 bx += gdb_ext.get(k).origin;
690
691 Box<dim,long int> output;
692 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);
693
694 // it intersect one sub-grid
695 if (bx.Intersect(flp_i,output))
696 {
697 // link
698
699 size_t g_id = box_int_recv.get(i).get(j).g_id;
700 add_eg_box<dim>(k,box_int_recv.get(i).get(j).cmb,output,
701 g_id,
702 gdb_ext.get(k).origin,
703 box_int_recv.get(i).get(j).bx.getP1(),
704 pib.bid);
705
706 eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
707
709 }
710 }
711
712 // now we check if exist a full match across the full intersected
713 // ghost parts
714
715 bool no_match = true;
716 for (size_t k = 0 ; k < eb_gid_list.last().eb_list.size() ; k++)
717 {
718 size_t eb_id = eb_gid_list.last().eb_list.get(k);
719
720 if (pib.bid.get(eb_id).g_e_box == box_int_recv.get(i).get(j).bx)
721 {
722 // full match found
723
724 eb_gid_list.last().full_match = eb_id;
725 no_match = false;
726
727 break;
728 }
729 }
730
731 // This is the case where a full match has not been found. In this case we
732 // generate an additional gdb_ext and local grid with only external ghost
733
734 if (no_match == true)
735 {
736 // Create a grid with the same size of the external ghost
737
738 size_t sz[dim];
739 for (size_t s = 0 ; s < dim ; s++)
740 {sz[s] = box_int_recv.get(i).get(j).bx.getHigh(s) - box_int_recv.get(i).get(j).bx.getLow(s) + 1;}
741
742 // Add an unlinked gdb_ext
743 // An unlinked gdb_ext is an empty domain with only a external ghost
744 // part
745 Box<dim,long int> output = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
746
747 GBoxes<dim> tmp;
748 tmp.GDbox = box_int_recv.get(i).get(j).bx;
749 tmp.GDbox -= tmp.GDbox.getP1();
750 tmp.origin = output.getP1();
751 for (size_t s = 0 ; s < dim ; s++)
752 {
753 // we set an invalid box, there is no-domain
754 tmp.Dbox.setLow(s,0);
755 tmp.Dbox.setHigh(s,-1);
756 }
757 tmp.k = (size_t)-1;
758 gdb_ext.add(tmp);
759
760 // create the local grid
761
762 loc_grid.add();
763 loc_grid.last().resize(sz);
764
765 // Add an external ghost box
766
767 size_t g_id = box_int_recv.get(i).get(j).g_id;
768 add_eg_box<dim>(gdb_ext.size()-1,box_int_recv.get(i).get(j).cmb,output,
769 g_id,
770 gdb_ext.get(gdb_ext.size()-1).origin,
771 box_int_recv.get(i).get(j).bx.getP1(),
772 pib.bid);
773
774 // now we map the received ghost box to the information of the
775 // external ghost box created
776 eb_gid_list.last().full_match = pib.bid.size() - 1;
777 eb_gid_list.last().eb_list.add(pib.bid.size() - 1);
779 }
780
781 // now we create lr_e_box
782
783 size_t fm = eb_gid_list.last().full_match;
784 size_t sub_id = pib.bid.get(fm).sub;
785
786 for ( ; pib_cnt < pib.bid.size() ; pib_cnt++)
787 {
788 pib.bid.get(pib_cnt).lr_e_box -= gdb_ext.get(sub_id).origin;
789 }
790
791 }
792 else
793 {
794 // Get the list of the sent sub-domains
795 // and recover the id of the sub-domain from
796 // the sent list
797 const openfpm::vector<size_t> & s_sub = dec.getSentSubdomains(p_id);
798
799 size_t sub_id = s_sub.get(send_list_id);
800
801 e_box_id<dim> bid_t;
802 bid_t.sub = sub_id;
803 bid_t.cmb = box_int_recv.get(i).get(j).cmb;
804 bid_t.cmb.sign_flip();
805 ::Box<dim,long int> ib = flip_box(box_int_recv.get(i).get(j).bx,box_int_recv.get(i).get(j).cmb,ginfo);
806 bid_t.g_e_box = ib;
807 bid_t.g_id = box_int_recv.get(i).get(j).g_id;
808 // Translate in local coordinate
809 Box<dim,long int> tb = ib;
810 tb -= gdb_ext.get(sub_id).origin;
811 bid_t.l_e_box = tb;
812
813 pib.bid.add(bid_t);
814 eb_gid_list.add();
815 eb_gid_list.last().eb_list.add(pib.bid.size()-1);
816 eb_gid_list.last().e_id = p_id;
817 eb_gid_list.last().full_match = pib.bid.size()-1;
818
820 }
821 }
822 }
823
824 init_e_g_box = true;
825 }
826
831 {
833
834 // Get the grid info
835 auto g = cd_sm.getGrid();
836
837 if (init_local_i_g_box == true) return;
838
839 // Get the number of sub-domains
840 for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
841 {
842 loc_ig_box.add();
843 auto&& pib = loc_ig_box.last();
844
845 for (size_t j = 0 ; j < dec.getLocalNIGhost(i) ; j++)
846 {
847 if (use_bx_def == true)
848 {
849 // Get the internal ghost boxes and transform into grid units
850 ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
851 ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
852
853 // Here we intersect the internal ghost box with the definition boxes
854 // this operation make sense when the grid is not defined in the full
855 // domain and we have to intersect the internal ghost box with all the box
856 // that define where the grid is defined
857 bx_intersect<dim>(bx_def,use_bx_def,ib,ibv);
858
859 for (size_t k = 0 ; k < ibv.size() ; k++)
860 {
861 // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
862 if (ibv.get(k).bx.isValid() == false)
863 {continue;}
864
865 pib.bid.add();
866 pib.bid.last().box = ibv.get(k).bx;
867
868 pib.bid.last().sub_gdb_ext = convert_to_gdb_ext(i,
869 ibv.get(k).id,
870 gdb_ext,
872
873 pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
874
875 // It will be filled later
876 pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
877 }
878 }
879 else
880 {
881 // Get the internal ghost boxes and transform into grid units
882 ::Box<dim,St> ib_dom = dec.getLocalIGhostBox(i,j);
883 ::Box<dim,long int> ib = cd_sm.convertDomainSpaceIntoGridUnits(ib_dom,dec.periodicity());
884
885 // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
886 if (ib.isValid() == false)
887 continue;
888
889 size_t sub_id = i;
890 size_t r_sub = dec.getLocalIGhostSub(i,j);
891
892 set_for_adjustment(sub_id,dec.getSubDomain(r_sub),
893 dec.getLocalIGhostPos(i,j),ib,ghost_int);
894
895 // Check if ib is valid if not it mean that the internal ghost does not contain information so skip it
896 if (ib.isValid() == false)
897 continue;
898
899 pib.bid.add();
900 pib.bid.last().box = ib;
901 pib.bid.last().sub = dec.getLocalIGhostSub(i,j);
902 pib.bid.last().k.add(dec.getLocalIGhostE(i,j));
903 pib.bid.last().cmb = dec.getLocalIGhostPos(i,j);
904 pib.bid.last().sub_gdb_ext = i;
905 }
906 }
907
908 if (use_bx_def == true)
909 {
910 // unfortunately boxes that define where the grid is located can generate
911 // additional internal ghost boxes
912
913 for (size_t j = gdb_ext_markers.get(i) ; j < gdb_ext_markers.get(i+1) ; j++)
914 {
915 // intersect within box in the save sub-domain
916
917 for (size_t k = gdb_ext_markers.get(i) ; k < gdb_ext_markers.get(i+1) ; k++)
918 {
919 if (j == k) {continue;}
920
921 // extend k and calculate the internal ghost box
922 Box<dim,long int> bx_e = gdb_ext.get(k).GDbox;
923 bx_e += gdb_ext.get(k).origin;
924 Box<dim,long int> bx = gdb_ext.get(j).Dbox;
925 bx += gdb_ext.get(j).origin;
926
927 Box<dim,long int> output;
928 if (bx.Intersect(bx_e, output) == true)
929 {
930 pib.bid.add();
931
932 pib.bid.last().box = output;
933
934 pib.bid.last().sub_gdb_ext = j;
935 pib.bid.last().sub = i;
936
937 // these ghost always in the quadrant zero
938 pib.bid.last().cmb.zero();
939
940 }
941 }
942 }
943 }
944
945 }
946
947
948 init_local_i_g_box = true;
949 }
950
955 {
956 // Get the grid info
957 auto g = cd_sm.getGrid();
958
959 if (init_local_e_g_box == true) return;
960
961 loc_eg_box.resize(dec.getNSubDomain());
962
963 // Get the number of sub-domain
964 for (size_t i = 0 ; i < dec.getNSubDomain() ; i++)
965 {
966 for (size_t j = 0 ; j < loc_ig_box.get(i).bid.size() ; j++)
967 {
968 long int volume_linked = 0;
969
970 size_t le_sub = loc_ig_box.get(i).bid.get(j).sub;
971 auto & pib = loc_eg_box.get(le_sub);
972
973 if (use_bx_def == true)
974 {
975
976 // We check if an external local ghost box intersect one
977 // or more sub-grids
978 for (size_t k = 0 ; k < gdb_ext.size() ; k++)
979 {
980 Box<dim,long int> bx = gdb_ext.get(k).Dbox;
981 bx += gdb_ext.get(k).origin;
982
983 Box<dim,long int> gbx = gdb_ext.get(k).GDbox;
984 gbx += gdb_ext.get(k).origin;
985
986 Box<dim,long int> output;
987 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);
988
989 bool intersect_domain = bx.Intersect(flp_i,output);
990 bool intersect_gdomain = gbx.Intersect(flp_i,output);
991
992 // it intersect one sub-grid
993 if (intersect_domain == false && intersect_gdomain == true)
994 {
995 // fill the link variable
996 loc_ig_box.get(i).bid.get(j).k.add(pib.bid.size());
997 size_t s = loc_ig_box.get(i).bid.get(j).k.last();
998
999 comb<dim> cmb = loc_ig_box.get(i).bid.get(j).cmb;
1000 cmb.sign_flip();
1001
1002 add_loc_eg_box(le_sub,
1003 loc_ig_box.get(i).bid.get(j).sub_gdb_ext,
1004 j,
1005 k,
1006 pib.bid,
1007 output,
1008 cmb);
1009
1010
1011 volume_linked += pib.bid.last().ebox.getVolumeKey();
1012 }
1013 }
1014 }
1015 else
1016 {
1017 size_t k = loc_ig_box.get(i).bid.get(j).sub;
1018 auto & pib = loc_eg_box.get(k);
1019
1020 size_t s = loc_ig_box.get(i).bid.get(j).k.get(0);
1021 pib.bid.resize(dec.getLocalNEGhost(k));
1022
1023 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);
1024 pib.bid.get(s).sub = dec.getLocalEGhostSub(k,s);
1025 pib.bid.get(s).cmb = loc_ig_box.get(i).bid.get(j).cmb;
1026 pib.bid.get(s).cmb.sign_flip();
1027 pib.bid.get(s).k = j;
1028 pib.bid.get(s).initialized = true;
1029 pib.bid.get(s).sub_gdb_ext = k;
1030 }
1031 }
1032 }
1033
1034 init_local_e_g_box = true;
1035 }
1036
1037
1043 inline void check_size(const size_t (& g_sz)[dim])
1044 {
1045 for (size_t i = 0 ; i < dim ; i++)
1046 {
1047 if (g_sz[i] < 2)
1048 {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " distributed grids with size smaller than 2 are not supported\n";}
1049 }
1050 }
1051
1057 inline void check_domain(const Box<dim,St> & dom)
1058 {
1059 for (size_t i = 0 ; i < dim ; i++)
1060 {
1061 if (dom.getLow(i) >= dom.getHigh(i))
1062 {std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " error the simulation domain is invalid\n";}
1063 }
1064 }
1065
1073 const Ghost<dim,long int> & g,
1074 bool use_bx_def)
1075 {
1076 // create gdb
1077 create_gdb_ext<dim,Decomposition>(gdb_ext,gdb_ext_markers,dec,cd_sm,bx_def,g,use_bx_def);
1078
1079 size_t n_grid = gdb_ext.size();
1080
1081 // create local grids for each hyper-cube
1082 loc_grid.resize(n_grid);
1083
1084 // Size of the grid on each dimension
1085 size_t l_res[dim];
1086
1087 // Allocate the grids
1088 for (size_t i = 0 ; i < n_grid ; i++)
1089 {
1090 SpaceBox<dim,long int> sp_tg = gdb_ext.get(i).GDbox;
1091
1092 // Get the size of the local grid
1093 // The boxes indicate the extension of the index the size
1094 // is this extension +1
1095 // for example a 1D box (interval) from 0 to 3 in one dimension have
1096 // the points 0,1,2,3 = so a total of 4 points
1097 for (size_t j = 0 ; j < dim ; j++)
1098 {l_res[j] = (sp_tg.getHigh(j) >= 0)?(sp_tg.getHigh(j)+1):0;}
1099
1100 // Set the dimensions of the local grid
1101 loc_grid.get(i).resize(l_res);
1102 }
1103 }
1104
1105
1112 inline void InitializeCellDecomposer(const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_old, const Box<dim,size_t> & ext)
1113 {
1114 // Initialize the cell decomposer
1115 cd_sm.setDimensions(cd_old,ext);
1116 }
1117
1124 inline void InitializeCellDecomposer(const size_t (& g_sz)[dim], const size_t (& bc)[dim])
1125 {
1126 // check that the grid has valid size
1128
1129 // get the size of the cell decomposer
1130 size_t c_g[dim];
1131 getCellDecomposerPar<dim>(c_g,g_sz,bc);
1132
1133 // Initialize the cell decomposer
1134 cd_sm.setDimensions(domain,c_g,0);
1135 }
1136
1143 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>())
1144 {
1145 // fill the global size of the grid
1146 for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
1147
1148 // Get the number of processor and calculate the number of sub-domain
1149 // for decomposition
1150 size_t n_proc = v_cl.getProcessingUnits();
1151 size_t n_sub = n_proc * v_sub_unit_factor;
1152
1153 // Calculate the maximum number (before merging) of sub-domain on
1154 // each dimension
1155 size_t div[dim];
1156 for (size_t i = 0 ; i < dim ; i++)
1157 {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/dim));}
1158
1159 if (g_dist.size(0) != 0)
1160 {
1161 for (size_t i = 0 ; i < dim ; i++)
1162 {div[i] = g_dist.size(i);}
1163 }
1164
1165 // Create the sub-domains
1166 dec.setParameters(div,domain,bc,ghost);
1167 dec.decompose(dec_options::DEC_SKIP_ICELL);
1168 }
1169
1175 inline void InitializeStructures(const size_t (& g_sz)[dim])
1176 {
1177 // an empty
1179
1180 // Ghost zero
1182
1183 InitializeStructures(g_sz,empty,zero,false);
1184 }
1185
1193 inline void InitializeStructures(const size_t (& g_sz)[dim],
1195 const Ghost<dim,long int> & g,
1196 bool use_bx_def)
1197 {
1198 // fill the global size of the grid
1199 for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
1200
1201 // Create local grid
1202 Create(bx,g,use_bx_def);
1203 }
1204
1205 // Ghost as integer
1207
1208protected:
1209
1218 {
1219 return gdb_ext.get(i).Dbox;
1220 }
1221
1230 static inline Ghost<dim,St> convert_ghost(const Ghost<dim,long int> & gd, const CellDecomposer_sm<dim,St,shift<dim,St>> & cd_sm)
1231 {
1232 Ghost<dim,St> gc;
1233
1234 // get the grid spacing
1235 Box<dim,St> sp = cd_sm.getCellBox();
1236
1237 // enlarge 0.001 of the spacing
1238 sp.magnify_fix_P1(1.1);
1239
1240 // set the ghost
1241 for (size_t i = 0 ; i < dim ; i++)
1242 {
1243 gc.setLow(i,gd.getLow(i)*(sp.getHigh(i)));
1244 gc.setHigh(i,gd.getHigh(i)*(sp.getHigh(i)));
1245 }
1246
1247 return gc;
1248 }
1249
1256 {
1257 this->v_sub_unit_factor = n_sub;
1258 }
1259
1260 void reset_ghost_structures()
1261 {
1263 ig_box.clear();
1264 init_i_g_box = false;
1265
1266 eg_box.clear();
1267 eb_gid_list.clear();
1268 init_e_g_box = false;
1269
1270 init_local_i_g_box = false;
1271 loc_ig_box.clear();
1272
1273 init_local_e_g_box = false;
1274 loc_eg_box.clear();
1275 }
1276
1277public:
1278
1281
1284
1286 typedef T value_type;
1287
1289 typedef St stype;
1290
1292 typedef Memory memory_type;
1293
1296
1298 static const unsigned int dims = dim;
1299
1305 inline const Box<dim,St> getDomain() const
1306 {
1307 return domain;
1308 }
1309
1318 {
1319 return pmul(Point<dim,St>(gdb_ext.get(i).origin), cd_sm.getCellBox().getP2()) + getDomain().getP1();
1320 }
1321
1329 inline St spacing(size_t i) const
1330 {
1331 return cd_sm.getCellBox().getHigh(i);
1332 }
1333
1339 size_t size() const
1340 {
1341 return ginfo_v.size();
1342 }
1343
1351 {
1352 setBackground_impl<T,decltype(loc_grid)> func(bv,loc_grid);
1353 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop>>(func);
1354 }
1355
1362 template<unsigned int p>
1363 void setBackgroundValue(const typename boost::mpl::at<typename T::type,boost::mpl::int_<p>>::type & bv)
1364 {
1365 for (size_t i = 0 ; i < loc_grid.size() ; i++)
1366 {loc_grid.get(i).template setBackgroundValue<p>(bv);}
1367 }
1368
1377 size_t size_local_inserted() const
1378 {
1379 size_t lins = 0;
1380
1381 for (size_t i = 0 ; i < loc_grid.size() ; i++)
1382 {lins += loc_grid.get(i).size_inserted();}
1383
1384 return lins;
1385 }
1386
1394 size_t size(size_t i) const
1395 {
1396 return ginfo_v.size(i);
1397 }
1398
1405 :grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>(g),
1406 domain(g.domain),
1407 ghost(g.ghost),
1409 loc_grid(g.loc_grid),
1411 dec(g.dec),
1413 gdb_ext(g.gdb_ext),
1416 cd_sm(g.cd_sm),
1417 v_cl(g.v_cl),
1421 ginfo(g.ginfo),
1422 ginfo_v(g.ginfo_v),
1425 {
1426#ifdef SE_CLASS2
1427 check_new(this,8,GRID_DIST_EVENT,4);
1428#endif
1429
1430 for (size_t i = 0 ; i < dim ; i++)
1431 {g_sz[i] = g.g_sz[i];}
1432 }
1433
1444 template<typename H>
1445 grid_dist_id(const grid_dist_id<dim,St,H,typename Decomposition::base_type,Memory,grid_cpu<dim,H>> & g,
1446 const Ghost<dim,long int> & gh,
1447 Box<dim,size_t> ext)
1448 :ghost_int(gh),dec(create_vcluster()),v_cl(create_vcluster())
1449 {
1450#ifdef SE_CLASS2
1451 check_new(this,8,GRID_DIST_EVENT,4);
1452#endif
1453
1454 size_t ext_dim[dim];
1455 for (size_t i = 0 ; i < dim ; i++) {ext_dim[i] = g.getGridInfoVoid().size(i) + ext.getKP1().get(i) + ext.getKP2().get(i);}
1456
1457 // Set the grid info of the extended grid
1458 ginfo.setDimensions(ext_dim);
1459 ginfo_v.setDimensions(ext_dim);
1460
1461 InitializeCellDecomposer(g.getCellDecomposer(),ext);
1462
1464
1465 // Extend the grid by the extension part and calculate the domain
1466
1467 for (size_t i = 0 ; i < dim ; i++)
1468 {
1469 g_sz[i] = g.size(i) + ext.getLow(i) + ext.getHigh(i);
1470
1471 if (g.getDecomposition().periodicity(i) == NON_PERIODIC)
1472 {
1473 this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i) - g.spacing(i) / 2.0);
1474 this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i) + g.spacing(i) / 2.0);
1475 }
1476 else
1477 {
1478 this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i));
1479 this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i));
1480 }
1481 }
1482
1483 dec.setParameters(g.getDecomposition(),ghost,this->domain);
1484
1485 // an empty
1487
1488 InitializeStructures(g.getGridInfoVoid().getSize(),empty,gh,false);
1489 }
1490
1498 template<typename Decomposition2>
1499 grid_dist_id(const Decomposition2 & dec,
1500 const size_t (& g_sz)[dim],
1501 const Ghost<dim,St> & ghost)
1502 :domain(dec.getDomain()),ghost(ghost),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),
1504 {
1505#ifdef SE_CLASS2
1506 check_new(this,8,GRID_DIST_EVENT,4);
1507#endif
1508
1509 InitializeCellDecomposer(g_sz,dec.periodicity());
1510
1511 this->dec = dec.duplicate(ghost);
1512
1514 }
1515
1523 grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1524 const Ghost<dim,St> & ghost)
1526 ginfo_v(g_sz),v_cl(create_vcluster()),ghost_int(INVALID_GHOST)
1527 {
1528#ifdef SE_CLASS2
1529 check_new(this,8,GRID_DIST_EVENT,4);
1530#endif
1531
1532 InitializeCellDecomposer(g_sz,dec.periodicity());
1533
1534 this->dec = dec.duplicate(ghost);
1535
1537 }
1538
1548 grid_dist_id(const Decomposition & dec, const size_t (& g_sz)[dim],
1549 const Ghost<dim,long int> & g)
1550 :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1552 {
1553 InitializeCellDecomposer(g_sz,dec.periodicity());
1554
1556 this->dec = dec.duplicate(ghost);
1557
1558 // an empty
1560
1561 // Initialize structures
1562 InitializeStructures(g_sz,empty,g,false);
1563 }
1564
1574 template<typename Decomposition2>
1575 grid_dist_id(const Decomposition2 & dec, const size_t (& g_sz)[dim],
1576 const Ghost<dim,long int> & g)
1577 :domain(dec.getDomain()),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),
1579 {
1580 InitializeCellDecomposer(g_sz,dec.periodicity());
1581
1583 this->dec = dec.duplicate(ghost);
1584
1585 // an empty
1587
1588 // Initialize structures
1589 InitializeStructures(g_sz,empty,g,false);
1590 }
1591
1601 grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],
1602 const Ghost<dim,long int> & g)
1603 :domain(dec.getDomain()),dec(dec),v_cl(create_vcluster()),ginfo(g_sz),
1605 {
1606#ifdef SE_CLASS2
1607 check_new(this,8,GRID_DIST_EVENT,4);
1608#endif
1609 InitializeCellDecomposer(g_sz,dec.periodicity());
1610
1612 this->dec = dec.duplicate(ghost);
1613
1614 // an empty
1616
1617 // Initialize structures
1618 InitializeStructures(g_sz,empty,g,false);
1619 }
1620
1630 grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g, size_t opt = 0)
1631 :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1632 {
1633 }
1634
1644 grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g, size_t opt = 0)
1645 :grid_dist_id(g_sz,domain,g,create_non_periodic<dim>(),opt)
1646 {
1647 }
1648
1659 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)
1660 :domain(domain),ghost(g),ghost_int(INVALID_GHOST),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1661 {
1662#ifdef SE_CLASS2
1663 check_new(this,8,GRID_DIST_EVENT,4);
1664#endif
1665
1666 if (opt >> 32 != 0)
1667 {this->setDecompositionGranularity(opt >> 32);}
1668
1669 check_domain(domain);
1673 }
1674
1675
1686 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>())
1687 :domain(domain),ghost_int(g),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz)
1688 {
1689#ifdef SE_CLASS2
1690 check_new(this,8,GRID_DIST_EVENT,4);
1691#endif
1692
1693 if (opt >> 32 != 0)
1694 {this->setDecompositionGranularity(opt >> 32);}
1695
1696 check_domain(domain);
1698
1700
1701 InitializeDecomposition(g_sz,p.bc,g_dec);
1702
1703 // an empty
1705
1706 // Initialize structures
1707 InitializeStructures(g_sz,empty,g,false);
1708 }
1709
1710
1725 grid_dist_id(const size_t (& g_sz)[dim],
1726 const Box<dim,St> & domain,
1727 const Ghost<dim,long int> & g,
1728 const periodicity<dim> & p,
1730 :domain(domain),dec(create_vcluster()),v_cl(create_vcluster()),ginfo(g_sz),ginfo_v(g_sz),gint(g)
1731 {
1732#ifdef SE_CLASS2
1733 check_new(this,8,GRID_DIST_EVENT,4);
1734#endif
1735
1738
1740
1743 this->bx_def = bx_def;
1744 this->use_bx_def = true;
1745 }
1746
1753 {
1754#ifdef SE_CLASS2
1755 check_valid(this,8);
1756#endif
1757 return ginfo;
1758 }
1759
1766 {
1767#ifdef SE_CLASS2
1768 check_valid(this,8);
1769#endif
1770 return ginfo_v;
1771 }
1772
1779 {
1780#ifdef SE_CLASS2
1781 check_valid(this,8);
1782#endif
1783 return dec;
1784 }
1785
1792 {
1793#ifdef SE_CLASS2
1794 check_valid(this,8);
1795#endif
1796 return dec;
1797 }
1798
1804 const CellDecomposer_sm<dim,St,shift<dim,St>> & getCellDecomposer() const
1805 {
1806#ifdef SE_CLASS2
1807 check_valid(this,8);
1808#endif
1809 return cd_sm;
1810 }
1811
1819 bool isInside(const grid_key_dx<dim> & gk) const
1820 {
1821#ifdef SE_CLASS2
1822 check_valid(this,8);
1823#endif
1824 for (size_t i = 0 ; i < dim ; i++)
1825 {
1826 if (gk.get(i) < 0 || gk.get(i) >= (long int)g_sz[i])
1827 {return false;}
1828 }
1829
1830 return true;
1831 }
1832
1838 size_t getLocalDomainSize() const
1839 {
1840#ifdef SE_CLASS2
1841 check_valid(this,8);
1842#endif
1843 size_t total = 0;
1844
1845 for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1846 {
1847 total += gdb_ext.get(i).Dbox.getVolumeKey();
1848 }
1849
1850 return total;
1851 }
1852
1859 {
1860#ifdef SE_CLASS2
1861 check_valid(this,8);
1862#endif
1863 size_t total = 0;
1864
1865 for (size_t i = 0 ; i < gdb_ext.size() ; i++)
1866 {
1867 total += gdb_ext.get(i).GDbox.getVolumeKey();
1868 }
1869
1870 return total;
1871 }
1872
1873
1880 {
1881#ifdef SE_CLASS2
1882 check_valid(this,8);
1883#endif
1884 return gdb_ext;
1885 }
1886
1893 {
1894#ifdef SE_CLASS2
1895 check_valid(this,8);
1896#endif
1897 gdb_ext_global.clear();
1898
1900 v_cl.execute();
1901
1902 size_t size_r;
1903 size_t size = gdb_ext_global.size();
1904
1905 if (v_cl.getProcessUnitID() == 0)
1906 {
1907 for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1908 v_cl.send(i,0,&size,sizeof(size_t));
1909
1910 size_r = size;
1911 }
1912 else
1913 v_cl.recv(0,0,&size_r,sizeof(size_t));
1914
1915 v_cl.execute();
1916
1917 gdb_ext_global.resize(size_r);
1918
1919
1920 if (v_cl.getProcessUnitID() == 0)
1921 {
1922 for (size_t i = 1; i < v_cl.getProcessingUnits(); i++)
1924 }
1925 else
1927
1928 v_cl.execute();
1929 }
1930
1931
1938 decltype(device_grid::type_of_subiterator()),
1939 FREE>
1941 {
1942#ifdef SE_CLASS2
1943 check_valid(this,8);
1944#endif
1945
1947 grid_key_dx<dim> one;
1948 one.one();
1949 stop = stop - one;
1950
1952 decltype(device_grid::type_of_subiterator()),
1953 FREE> it(loc_grid_old,gdb_ext_old,stop);
1954
1955 return it;
1956 }
1957
1969 {
1971 return it_dec;
1972 }
1973
1974#ifdef __NVCC__
1975
1980 template<typename lambda_t2>
1981 void setPoints(lambda_t2 f2)
1982 {
1983 auto it = getGridIteratorGPU();
1984
1985 it.template launch<1>(launch_set_dense<dim>(),f2);
1986 }
1987
1994 template<typename lambda_t2>
1995 void setPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t2 f2)
1996 {
1997 auto it = getGridIteratorGPU(k1,k2);
1998
1999 it.template launch<0>(launch_set_dense<dim>(),f2);
2000 }
2001
2007 template<typename lambda_t1, typename lambda_t2>
2008 void addPoints(lambda_t1 f1, lambda_t2 f2)
2009 {
2010 auto it = getGridIteratorGPU();
2011 it.setGPUInsertBuffer(1);
2012
2013 it.template launch<1>(launch_insert_sparse(),f1,f2);
2014 }
2015
2023 template<typename lambda_t1, typename lambda_t2>
2024 void addPoints(grid_key_dx<dim> k1, grid_key_dx<dim> k2, lambda_t1 f1, lambda_t2 f2)
2025 {
2026 auto it = getGridIteratorGPU(k1,k2);
2027 it.setGPUInsertBuffer(1);
2028
2029 it.template launch<1>(launch_insert_sparse(),f1,f2);
2030 }
2031
2046 getGridIteratorGPU(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop)
2047 {
2049 return it_dec;
2050 }
2051
2063 getGridIteratorGPU()
2064 {
2066 return it_dec;
2067 }
2068
2069#endif
2070
2082 {
2084 return it_dec;
2085 }
2086
2098 {
2099 grid_key_dx<dim> start;
2100 grid_key_dx<dim> stop;
2101 for (size_t i = 0; i < dim; i++)
2102 {
2103 start.set_d(i, 0);
2104 stop.set_d(i, g_sz[i] - 1);
2105 }
2106
2108 return it_dec;
2109 }
2110
2117 decltype(device_grid::type_of_subiterator()),FREE>
2119 {
2120#ifdef SE_CLASS2
2121 check_valid(this,8);
2122#endif
2123
2125 grid_key_dx<dim> one;
2126 one.one();
2127 stop = stop - one;
2128
2130 decltype(device_grid::type_of_subiterator()),
2131 FREE> it(loc_grid,gdb_ext,stop);
2132
2133 return it;
2134 }
2135
2143 template<unsigned int Np>
2145 decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
2146 FREE,
2148 getDomainIteratorStencil(const grid_key_dx<dim> (& stencil_pnt)[Np]) const
2149 {
2150#ifdef SE_CLASS2
2151 check_valid(this,8);
2152#endif
2153
2155 grid_key_dx<dim> one;
2156 one.one();
2157 stop = stop - one;
2158
2160 decltype(device_grid::template type_of_subiterator<stencil_offset_compute<dim,Np>>()),
2161 FREE,
2162 stencil_offset_compute<dim,Np>> it(loc_grid,gdb_ext,stop,stencil_pnt);
2163
2164 return it;
2165 }
2166
2173 decltype(device_grid::type_of_iterator()),
2174 FIXED>
2176 {
2177#ifdef SE_CLASS2
2178 check_valid(this,8);
2179#endif
2180 grid_key_dx<dim> stop;
2181 for (size_t i = 0 ; i < dim ; i++)
2182 {stop.set_d(i,0);}
2183
2185 decltype(device_grid::type_of_iterator()),
2186 FIXED> it(loc_grid,gdb_ext,stop);
2187
2188 return it;
2189 }
2190
2205 const grid_key_dx<dim> & stop) const
2206 {
2207#ifdef SE_CLASS2
2208 check_valid(this,8);
2209#endif
2211
2212 return it;
2213 }
2214
2227 grid_dist_iterator_sub<dim,device_grid> getSubDomainIterator(const long int (& start)[dim], const long int (& stop)[dim]) const
2228 {
2230
2231 return it;
2232 }
2233
2236 {
2237#ifdef SE_CLASS2
2238 check_delete(this);
2239#endif
2240 dec.decRef();
2241 }
2242
2249 {
2250#ifdef SE_CLASS2
2251 check_valid(this,8);
2252#endif
2253 return v_cl;
2254 }
2255
2261 {
2262 for (int i = 0 ; i < loc_grid.size() ; i++)
2263 {
2264 loc_grid.get(i).removeUnusedBuffers();
2265 }
2266 }
2267
2273 bool is_staggered() const
2274 {
2275 return false;
2276 }
2277
2288 template <typename bg_key> inline void remove(const grid_dist_key_dx<dim,bg_key> & v1)
2289 {
2290#ifdef SE_CLASS2
2291 check_valid(this,8);
2292#endif
2293 return loc_grid.get(v1.getSub()).remove(v1.getKey());
2294 }
2295
2306 template <typename bg_key> inline void remove_no_flush(const grid_dist_key_dx<dim,bg_key> & v1)
2307 {
2308#ifdef SE_CLASS2
2309 check_valid(this,8);
2310#endif
2311 return loc_grid.get(v1.getSub()).remove_no_flush(v1.getKey());
2312 }
2313
2314
2315 template<typename ... v_reduce>
2316 void flush(flush_type opt = flush_type::FLUSH_ON_HOST)
2317 {
2318 for (size_t i = 0 ; i < loc_grid.size() ; i++)
2319 {
2320 loc_grid.get(i).template flush<v_reduce ...>(v_cl.getgpuContext(),opt);
2321 }
2322 }
2323
2334 inline void flush_remove()
2335 {
2336#ifdef SE_CLASS2
2337 check_valid(this,8);
2338#endif
2339 for (size_t i = 0 ; i < loc_grid.size() ; i++)
2340 {loc_grid.get(i).flush_remove();}
2341 }
2342
2356 template <unsigned int p,typename bg_key>inline auto insert(const grid_dist_key_dx<dim,bg_key> & v1)
2357 -> decltype(loc_grid.get(v1.getSub()).template insert<p>(v1.getKey()))
2358 {
2359#ifdef SE_CLASS2
2360 check_valid(this,8);
2361#endif
2362
2363 return loc_grid.get(v1.getSub()).template insert<p>(v1.getKey());
2364 }
2365
2366
2383 template <unsigned int p,typename bg_key>inline auto insertFlush(const grid_dist_key_dx<dim,bg_key> & v1)
2384 -> decltype(loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey()))
2385 {
2386#ifdef SE_CLASS2
2387 check_valid(this,8);
2388#endif
2389
2390 return loc_grid.get(v1.getSub()).template insertFlush<p>(v1.getKey());
2391 }
2392
2409 template <typename bg_key>inline auto insertFlush(const grid_dist_key_dx<dim,bg_key> & v1)
2410 -> decltype(loc_grid.get(v1.getSub()).template insertFlush(v1.getKey()))
2411 {
2412#ifdef SE_CLASS2
2413 check_valid(this,8);
2414#endif
2415
2416 return loc_grid.get(v1.getSub()).template insertFlush(v1.getKey());
2417 }
2418
2427 template <unsigned int p, typename bg_key>
2428 inline auto get(const grid_dist_key_dx<dim,bg_key> & v1) const
2429 -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
2430 {
2431#ifdef SE_CLASS2
2432 check_valid(this,8);
2433#endif
2434 return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2435 }
2436
2437
2446 template <unsigned int p, typename bg_key>
2447 inline auto get(const grid_dist_key_dx<dim,bg_key> & v1)
2448 -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2449 {
2450#ifdef SE_CLASS2
2451 check_valid(this,8);
2452#endif
2453 return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2454 }
2455
2464 template <unsigned int p = 0>
2465 inline auto get(const grid_dist_g_dx<device_grid> & v1) const
2466 -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2467 {
2468#ifdef SE_CLASS2
2469 check_valid(this,8);
2470#endif
2471 return v1.getSub()->template get<p>(v1.getKey());
2472 }
2473
2482 template <unsigned int p = 0>
2483 inline auto get(const grid_dist_g_dx<device_grid> & v1) -> decltype(v1.getSub()->template get<p>(v1.getKey()))
2484 {
2485#ifdef SE_CLASS2
2486 check_valid(this,8);
2487#endif
2488 return v1.getSub()->template get<p>(v1.getKey());
2489 }
2490
2499 template <unsigned int p = 0>
2500 inline auto get(const grid_dist_lin_dx & v1) const -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2501 {
2502#ifdef SE_CLASS2
2503 check_valid(this,8);
2504#endif
2505 return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2506 }
2507
2516 template <unsigned int p = 0>
2517 inline auto get(const grid_dist_lin_dx & v1) -> decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))
2518 {
2519#ifdef SE_CLASS2
2520 check_valid(this,8);
2521#endif
2522 return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
2523 }
2524
2533 template <typename bg_key>
2535 {
2536#ifdef SE_CLASS2
2537 check_valid(this,8);
2538#endif
2539 Point<dim,St> p;
2540
2541 for (int i = 0 ; i < dim ; i++)
2542 {
2543 p.get(i) = (gdb_ext.get(v1.getSub()).origin.get(i) + v1.getKeyRef().get(i)) * this->spacing(i) + domain.getLow(i);
2544 }
2545
2546 return p;
2547 }
2548
2556 template<typename bg_key>
2557 inline bool existPoint(const grid_dist_key_dx<dim,bg_key> & v1) const
2558 {
2559 return loc_grid.get(v1.getSub()).existPoint(v1.getKey());
2560 }
2561
2570 template <unsigned int p = 0, typename bgkey>
2571 inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) const -> decltype(this->template get<p>(v1))
2572 {
2573 return this->template get<p>(v1);
2574 }
2575
2584 template <unsigned int p = 0, typename bgkey>
2585 inline auto getProp(const grid_dist_key_dx<dim,bgkey> & v1) -> decltype(this->template get<p>(v1))
2586 {
2587 return this->template get<p>(v1);
2588 }
2589
2595 template<int... prp> void ghost_get(size_t opt = 0)
2596 {
2597#ifdef SE_CLASS2
2598 check_valid(this,8);
2599#endif
2600
2601 // Convert the ghost internal boxes into grid unit boxes
2602 create_ig_box();
2603
2604 // Convert the ghost external boxes into grid unit boxes
2605 create_eg_box();
2606
2607 // Convert the local ghost internal boxes into grid unit boxes
2609
2610 // Convert the local external ghost boxes into grid unit boxes
2612
2614 eg_box,
2615 loc_ig_box,
2616 loc_eg_box,
2617 gdb_ext,
2619 use_bx_def,
2620 loc_grid,
2621 ginfo_v,
2623 opt);
2624 }
2625
2631 template<template<typename,typename> class op,int... prp> void ghost_put()
2632 {
2633#ifdef SE_CLASS2
2634 check_valid(this,8);
2635#endif
2636
2637 // Convert the ghost internal boxes into grid unit boxes
2638 create_ig_box();
2639
2640 // Convert the ghost external boxes into grid unit boxes
2641 create_eg_box();
2642
2643 // Convert the local ghost internal boxes into grid unit boxes
2645
2646 // Convert the local external ghost boxes into grid unit boxes
2648
2650 ig_box,
2651 eg_box,
2652 loc_ig_box,
2653 loc_eg_box,
2654 gdb_ext,
2655 loc_grid,
2657 }
2658
2659
2673 {
2674 if (T::noPointers() == true && use_memcpy)
2675 {
2676 for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2677 {
2678 auto & gs_src = this->get_loc_grid(i).getGrid();
2679
2680 long int start = gs_src.LinId(gdb_ext.get(i).Dbox.getKP1());
2681 long int stop = gs_src.LinId(gdb_ext.get(i).Dbox.getKP2());
2682
2683 if (stop < start) {continue;}
2684
2685 void * dst = static_cast<void *>(static_cast<char *>(this->get_loc_grid(i).getPointer()) + start*sizeof(T));
2686 void * src = static_cast<void *>(static_cast<char *>(g.get_loc_grid(i).getPointer()) + start*sizeof(T));
2687
2688 memcpy(dst,src,sizeof(T) * (stop + 1 - start));
2689 }
2690 }
2691 else
2692 {
2693 grid_key_dx<dim> cnt[1];
2694 cnt[0].zero();
2695
2696 for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2697 {
2698 auto & dst = this->get_loc_grid(i);
2699 auto & src = g.get_loc_grid(i);
2700
2701 auto it = this->get_loc_grid_iterator_stencil(i,cnt);
2702
2703 while (it.isNext())
2704 {
2705 // center point
2706 auto Cp = it.template getStencil<0>();
2707
2708 dst.insert_o(Cp) = src.get_o(Cp);
2709
2710 ++it;
2711 }
2712 }
2713 }
2714
2715 return *this;
2716 }
2717
2731 {
2732 grid_key_dx<dim> cnt[1];
2733 cnt[0].zero();
2734
2735 for (size_t i = 0 ; i < this->getN_loc_grid() ; i++)
2736 {
2737 auto & dst = this->get_loc_grid(i);
2738 auto & src = g.get_loc_grid(i);
2739
2740 dst = src;
2741 }
2742 return *this;
2743 }
2744
2751 {
2752 return cd_sm.getCellBox().getP2();
2753 }
2754
2766 {
2767#ifdef SE_CLASS2
2768 check_valid(this,8);
2769#endif
2770 // Get the sub-domain id
2771 size_t sub_id = k.getSub();
2772
2773 grid_key_dx<dim> k_glob = k.getKey();
2774
2775 // shift
2776 k_glob = k_glob + gdb_ext.get(sub_id).origin;
2777
2778 return k_glob;
2779 }
2780
2789 template <typename Model>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2790 {
2791 CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2792
2794 auto & dist = getDecomposition().getDistribution();
2795
2796 cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2797
2798 // Invert the id to positional
2799
2800 Point<dim,St> p;
2801 for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2802 {
2803 dist.getSubSubDomainPos(i,p);
2804 dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1 + md.resolution(p));
2805 }
2806
2807 dec.computeCommunicationAndMigrationCosts(ts);
2808
2809 dist.setDistTol(md.distributionTol());
2810 }
2811
2816 template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, unsigned int N, typename lambda_f, typename ... ArgsT >
2817 void conv(int (& stencil)[N][dim], grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2818 {
2819 for (int i = 0 ; i < loc_grid.size() ; i++)
2820 {
2821 Box<dim,long int> inte;
2822
2823 Box<dim,long int> base;
2824 for (int j = 0 ; j < dim ; j++)
2825 {
2826 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2827 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2828 }
2829
2830 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2831
2832 bool overlap = dom.Intersect(base,inte);
2833
2834 if (overlap == true)
2835 {
2836 loc_grid.get(i).template conv<prop_src,prop_dst,stencil_size>(stencil,inte.getKP1(),inte.getKP2(),func,args...);
2837 }
2838 }
2839 }
2840
2845 template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2846 void conv_cross(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2847 {
2848 for (int i = 0 ; i < loc_grid.size() ; i++)
2849 {
2850 Box<dim,long int> inte;
2851
2852 Box<dim,long int> base;
2853 for (int j = 0 ; j < dim ; j++)
2854 {
2855 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2856 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2857 }
2858
2859 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2860
2861 bool overlap = dom.Intersect(base,inte);
2862
2863 if (overlap == true)
2864 {
2865 loc_grid.get(i).template conv_cross<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2866 }
2867 }
2868 }
2869
2874 template<unsigned int prop_src, unsigned int prop_dst, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2875 void conv_cross_b(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2876 {
2877 for (int i = 0 ; i < loc_grid.size() ; i++)
2878 {
2879 Box<dim,long int> inte;
2880
2881 Box<dim,long int> base;
2882 for (int j = 0 ; j < dim ; j++)
2883 {
2884 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2885 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2886 }
2887
2888 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2889
2890 bool overlap = dom.Intersect(base,inte);
2891
2892 if (overlap == true)
2893 {
2894 loc_grid.get(i).template conv_cross_b<prop_src,prop_dst,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2895 }
2896 }
2897 }
2898
2903 template<unsigned int stencil_size, typename v_type, typename lambda_f, typename ... ArgsT >
2904 void conv_cross_ids(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
2905 {
2906 for (int i = 0 ; i < loc_grid.size() ; i++)
2907 {
2908 Box<dim,long int> inte;
2909
2910 Box<dim,long int> base;
2911 for (int j = 0 ; j < dim ; j++)
2912 {
2913 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2914 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2915 }
2916
2917 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2918
2919 bool overlap = dom.Intersect(base,inte);
2920
2921 if (overlap == true)
2922 {
2923 loc_grid.get(i).template conv_cross_ids<stencil_size,v_type>(inte.getKP1(),inte.getKP2(),func,args...);
2924 }
2925 }
2926 }
2927
2932 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 >
2933 void conv2(int (& stencil)[N][dim], grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2934 {
2935 for (int i = 0 ; i < loc_grid.size() ; i++)
2936 {
2937 Box<dim,long int> inte;
2938
2939 Box<dim,long int> base;
2940 for (int j = 0 ; j < dim ; j++)
2941 {
2942 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2943 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2944 }
2945
2946 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2947
2948 bool overlap = dom.Intersect(base,inte);
2949
2950 if (overlap == true)
2951 {
2952 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...);
2953 }
2954 }
2955 }
2956
2961 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 >
2962 void conv2(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2963 {
2964 for (int i = 0 ; i < loc_grid.size() ; i++)
2965 {
2966 Box<dim,long int> inte;
2967
2968 Box<dim,long int> base;
2969 for (int j = 0 ; j < dim ; j++)
2970 {
2971 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2972 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
2973 }
2974
2975 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
2976
2977 bool overlap = dom.Intersect(base,inte);
2978
2979 if (overlap == true)
2980 {
2981 loc_grid.get(i).template conv2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
2982 }
2983 }
2984 }
2985
2990 template<unsigned int prop_src1, unsigned int prop_dst1, unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
2991 void conv(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
2992 {
2993 for (int i = 0 ; i < loc_grid.size() ; i++)
2994 {
2995 Box<dim,long int> inte;
2996
2997 Box<dim,long int> base;
2998 for (int j = 0 ; j < dim ; j++)
2999 {
3000 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3001 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3002 }
3003
3004 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3005
3006 bool overlap = dom.Intersect(base,inte);
3007
3008 if (overlap == true)
3009 {
3010 loc_grid.get(i).template conv<prop_src1,prop_dst1,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3011 }
3012 }
3013 }
3014
3019 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 >
3020 void conv2_b(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
3021 {
3022 for (int i = 0 ; i < loc_grid.size() ; i++)
3023 {
3024 Box<dim,long int> inte;
3025
3026 Box<dim,long int> base;
3027 for (int j = 0 ; j < dim ; j++)
3028 {
3029 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3030 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3031 }
3032
3033 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3034
3035 bool overlap = dom.Intersect(base,inte);
3036
3037 if (overlap == true)
3038 {
3039 loc_grid.get(i).template conv2_b<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3040 }
3041 }
3042 }
3043
3048 template<unsigned int prop_src1, unsigned int prop_src2, unsigned int prop_src3,
3049 unsigned int prop_dst1, unsigned int prop_dst2, unsigned int prop_dst3,
3050 unsigned int stencil_size, typename lambda_f, typename ... ArgsT >
3051 void conv3_b(grid_key_dx<dim> start, grid_key_dx<dim> stop , lambda_f func, ArgsT ... args)
3052 {
3053 for (int i = 0 ; i < loc_grid.size() ; i++)
3054 {
3055 Box<dim,long int> inte;
3056
3057 Box<dim,long int> base;
3058 for (int j = 0 ; j < dim ; j++)
3059 {
3060 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3061 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3062 }
3063
3064 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3065
3066 bool overlap = dom.Intersect(base,inte);
3067
3068 if (overlap == true)
3069 {
3070 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...);
3071 }
3072 }
3073 }
3074
3075 template<typename NNtype>
3076 void findNeighbours()
3077 {
3078 for (int i = 0 ; i < loc_grid.size() ; i++)
3079 {
3080 loc_grid.get(i).findNeighbours();
3081 }
3082 }
3083
3088 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 >
3089 void conv_cross2(grid_key_dx<3> start, grid_key_dx<3> stop , lambda_f func, ArgsT ... args)
3090 {
3091 for (int i = 0 ; i < loc_grid.size() ; i++)
3092 {
3093 Box<dim,long int> inte;
3094
3095 Box<dim,long int> base;
3096 for (int j = 0 ; j < dim ; j++)
3097 {
3098 base.setLow(j,(long int)start.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3099 base.setHigh(j,(long int)stop.get(j) - (long int)gdb_ext.get(i).origin.get(j));
3100 }
3101
3102 Box<dim,long int> dom = gdb_ext.get(i).Dbox;
3103
3104 bool overlap = dom.Intersect(base,inte);
3105
3106 if (overlap == true)
3107 {
3108 loc_grid.get(i).template conv_cross2<prop_src1,prop_src2,prop_dst1,prop_dst2,stencil_size>(inte.getKP1(),inte.getKP2(),func,args...);
3109 }
3110 }
3111 }
3112
3124 bool write(std::string output, size_t opt = VTK_WRITER | FORMAT_BINARY )
3125 {
3126#ifdef SE_CLASS2
3127 check_valid(this,8);
3128#endif
3129
3130 file_type ft = file_type::ASCII;
3131
3132 if (opt & FORMAT_BINARY)
3133 {ft = file_type::BINARY;}
3134
3135 // Create a writer and write
3137 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3138 {
3139 Point<dim,St> offset = getOffset(i);
3140
3141 if (opt & PRINT_GHOST)
3142 {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).GDbox);}
3143 else
3144 {vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);}
3145 }
3146 vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk", prp_names, "grids", ft);
3147
3148 return true;
3149 }
3150
3156 bool write_debug(std::string output)
3157 {
3158 for (int i = 0 ; i < getN_loc_grid() ; i++)
3159 {
3160 Point<dim,St> sp;
3161 Point<dim,St> offset;
3162
3163 for (int j = 0 ; j < dim ; j++)
3164 {sp.get(j) = this->spacing(j);}
3165
3166 offset = gdb_ext.get(i).origin;
3167
3168 get_loc_grid(i).write_debug(output + "_" + std::to_string(i) + "_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk",sp,offset);
3169 }
3170
3171 return true;
3172 }
3173
3186 bool write_frame(std::string output, size_t i, size_t opt = VTK_WRITER | FORMAT_ASCII)
3187 {
3188#ifdef SE_CLASS2
3189 check_valid(this,8);
3190#endif
3191 file_type ft = file_type::ASCII;
3192
3193 if (opt & FORMAT_BINARY)
3194 ft = file_type::BINARY;
3195
3196 // Create a writer and write
3198 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3199 {
3200 Point<dim,St> offset = getOffset(i);
3201 vtk_g.add(loc_grid.get(i),offset,cd_sm.getCellBox().getP2(),gdb_ext.get(i).Dbox);
3202 }
3203 vtk_g.write(output + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(i) + ".vtk",prp_names,"grids",ft);
3204
3205 return true;
3206 }
3207
3208
3209
3218 {
3219 return loc_grid.get(i);
3220 }
3221
3229 const device_grid & get_loc_grid(size_t i) const
3230 {
3231 return loc_grid.get(i);
3232 }
3233
3242 {
3243 return grid_key_dx_iterator_sub<dim,no_stencil>(loc_grid.get(i).getGrid(),
3244 gdb_ext.get(i).Dbox.getKP1(),
3245 gdb_ext.get(i).Dbox.getKP2());
3246 }
3247
3255 template<unsigned int Np>
3256 grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>
3257 get_loc_grid_iterator_stencil(size_t i,const grid_key_dx<dim> (& stencil_pnt)[Np])
3258 {
3259 return grid_key_dx_iterator_sub<dim,stencil_offset_compute<dim,Np>,typename device_grid::linearizer_type>(loc_grid.get(i).getGrid(),
3260 gdb_ext.get(i).Dbox.getKP1(),
3261 gdb_ext.get(i).Dbox.getKP2(),
3262 stencil_pnt);
3263 }
3264
3270 size_t getN_loc_grid() const
3271 {
3272 return loc_grid.size();
3273 }
3274
3275
3283 long int who()
3284 {
3285#ifdef SE_CLASS2
3286 return check_whoami(this,8);
3287#else
3288 return -1;
3289#endif
3290 }
3291
3297 {
3298 size_t tot_volume = 0;
3299
3300 std::cout << "-------- External Ghost boxes ---------- " << std::endl;
3301
3302 for (size_t i = 0 ; i < eg_box.size() ; i++)
3303 {
3304 std::cout << "Processor: " << eg_box.get(i).prc << " Boxes:" << std::endl;
3305
3306 for (size_t j = 0; j < eg_box.get(i).bid.size() ; j++)
3307 {
3308 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;
3309 tot_volume += eg_box.get(i).bid.get(j).g_e_box.getVolumeKey();
3310 }
3311 }
3312
3313 std::cout << "TOT volume external ghost " << tot_volume << std::endl;
3314
3315 std::cout << "-------- Internal Ghost boxes ---------- " << std::endl;
3316
3317 tot_volume = 0;
3318 for (size_t i = 0 ; i < ig_box.size() ; i++)
3319 {
3320 std::cout << "Processor: " << ig_box.get(i).prc << " Boxes:" << std::endl;
3321
3322 for (size_t j = 0 ; j < ig_box.get(i).bid.size() ; j++)
3323 {
3324 std::cout << " Box: " << ig_box.get(i).bid.get(j).box.toString() << " Id: " << ig_box.get(i).bid.get(j).g_id << std::endl;
3325 tot_volume += ig_box.get(i).bid.get(j).box.getVolumeKey();
3326 }
3327 }
3328
3329 std::cout << "TOT volume internal ghost " << tot_volume << std::endl;
3330 }
3331
3340 {
3341 prp_names = names;
3342 }
3343
3352 {
3353 return prp_names;
3354 }
3355
3362 void clear()
3363 {
3364 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3365 {loc_grid.get(i).clear();}
3366 }
3367
3374 void construct_link(self & grid_up, self & grid_dw)
3375 {
3376 for (int i = 0 ; i < loc_grid.size() ; i++)
3377 {
3378 loc_grid.get(i).construct_link(grid_up.get_loc_grid(i),grid_dw.get_loc_grid(i),v_cl.getgpuContext());
3379 }
3380 }
3381
3389 {
3390 for (int i = 0 ; i < loc_grid.size() ; i++)
3391 {
3392 Point<dim,int> p_dw;
3393 for(int j = 0 ; j < dim ; j++)
3394 {p_dw.get(j) = mvof.get(i).dw.get(j);}
3395
3396 loc_grid.get(i).construct_link_dw(grid_dw.get_loc_grid(i),gdb_ext.get(i).Dbox,p_dw,v_cl.getgpuContext());
3397 }
3398 }
3399
3407 {
3408 for (int i = 0 ; i < loc_grid.size() ; i++)
3409 {
3410 Point<dim,int> p_up;
3411 for(int j = 0 ; j < dim ; j++)
3412 {p_up.get(j) = mvof.get(i).up.get(j);}
3413
3414 loc_grid.get(i).construct_link_up(grid_up.get_loc_grid(i),gdb_ext.get(i).Dbox,p_up,v_cl.getgpuContext());
3415 }
3416 }
3417
3424 template<typename stencil_type>
3426 {
3427 for (int i = 0 ; i < loc_grid.size() ; i++)
3428 {
3429 // we limit to the domain subset for tagging
3430
3431 Box_check<dim,unsigned int> chk(gdb_ext.get(i).Dbox);
3432
3433
3434 loc_grid.get(i).template tagBoundaries<stencil_type>(v_cl.getgpuContext(),chk);
3435 }
3436 }
3437
3441 void map(size_t opt = 0)
3442 {
3443 // Save the background values
3444 T bv;
3445
3446 copy_aggregate_dual<decltype(loc_grid.get(0).getBackgroundValue()),
3447 T> ca(loc_grid.get(0).getBackgroundValue(),bv);
3448
3449 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(ca);
3450
3451 if (!(opt & NO_GDB_EXT_SWITCH))
3452 {
3455
3457 }
3458
3460
3461
3462 typedef typename to_int_sequence<0,T::max_prop-1>::type result;
3463
3465
3466 loc_grid_old.clear();
3467 loc_grid_old.shrink_to_fit();
3468 gdb_ext_old.clear();
3469
3470 // reset ghost structure to recalculate
3471 reset_ghost_structures();
3472
3473 // Reset the background values
3475 }
3476
3482 inline void save(const std::string & filename) const
3483 {
3485
3486 h5s.save(filename,loc_grid,gdb_ext);
3487 }
3488
3494 inline void load(const std::string & filename)
3495 {
3497
3498 h5l.load<device_grid>(filename,loc_grid_old,gdb_ext_old);
3499
3500 if (v_cl.size() != 1)
3501 {
3502 // move information from host to device
3503 for (int i = 0 ; i < loc_grid_old.size() ; i++)
3504 {loc_grid_old.get(i).template hostToDevice<0>();}
3505 // Map the distributed grid
3506 size_t opt_ = NO_GDB_EXT_SWITCH;
3507 if (std::is_same<Memory,CudaMemory>::value == true)
3508 {opt_ |= RUN_ON_DEVICE;}
3509 map(opt_);
3510 }
3511 else
3512 {
3513 device_grid_copy<device_grid::isCompressed()>::pre_load(gdb_ext_old,loc_grid_old,gdb_ext,loc_grid);
3514 for (int i = 0 ; i < gdb_ext_old.size() ; i++)
3515 {
3516 auto & lg = loc_grid_old.get(i);
3517 auto it_src = lg.getIterator(gdb_ext_old.get(i).Dbox.getKP1(),gdb_ext_old.get(i).Dbox.getKP2());
3518 auto & dg = loc_grid.get(0);
3519 grid_key_dx<dim> kp1 = gdb_ext.get(0).Dbox.getKP1();
3520
3521 grid_key_dx<dim> orig;
3522 for (int j = 0 ; j < dim ; j++)
3523 {
3524 orig.set_d(j,gdb_ext_old.get(i).origin.get(j));
3525 }
3526
3527 while (it_src.isNext())
3528 {
3529 auto key = it_src.get();
3530 grid_key_dx<dim> key_dst;
3531
3532 for (int j = 0 ; j < dim ; j++)
3533 {key_dst.set_d(j,key.get(j) + orig.get(j) + kp1.get(j));}
3534
3535 device_grid_copy<device_grid::isCompressed()>::assign(key,key_dst,dg,lg);
3536
3537 ++it_src;
3538 }
3539
3540 dg.template hostToDevice<0>();
3541 }
3542 }
3543 }
3544
3550 template <typename stencil = no_stencil>
3552 {
3554 }
3555
3562 {
3563 return this->loc_ig_box;
3564 }
3565
3572 {
3573 return this->ig_box;
3574 }
3575
3576 void print_stats()
3577 {
3578 std::cout << "-- REPORT --" << std::endl;
3579#ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3580 std::cout << "Processor: " << v_cl.rank() << " Time spent in packing data: " << tot_pack << std::endl;
3581 std::cout << "Processor: " << v_cl.rank() << " Time spent in sending and receving data: " << tot_sendrecv << std::endl;
3582 std::cout << "Processor: " << v_cl.rank() << " Time spent in merging: " << tot_merge << std::endl;
3583 std::cout << "Processor: " << v_cl.rank() << " Time spent in local merging: " << tot_loc_merge << std::endl;
3584#else
3585
3586 std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3587
3588#endif
3589 }
3590
3591 void clear_stats()
3592 {
3593#ifdef ENABLE_GRID_DIST_ID_PERF_STATS
3594 tot_pack = 0;
3595 tot_sendrecv = 0;
3596 tot_merge = 0;
3597#else
3598
3599 std::cout << "Enable ENABLE_GRID_DIST_ID_PERF_STATS if you want to activate this feature" << std::endl;
3600
3601#endif
3602 }
3603
3604#ifdef __NVCC__
3605
3611 void setNumberOfInsertPerThread(size_t n_ins)
3612 {
3613 gpu_n_insert_thread = n_ins;
3614 }
3615
3616 template<typename func_t,typename it_t, typename ... args_t>
3617 void iterateGridGPU(it_t & it, args_t ... args)
3618 {
3619 // setGPUInsertBuffer must be called in anycase even with 0 points to insert
3620 // the loop "it.isNextGrid()" does not guarantee to call it for all local grids
3621 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3622 {loc_grid.get(i).setGPUInsertBuffer(0ul,1ul);}
3623
3624 while(it.isNextGrid())
3625 {
3626 Box<dim,size_t> b = it.getGridBox();
3627
3628 size_t i = it.getGridId();
3629
3630 auto ite = loc_grid.get(i).getGridGPUIterator(b.getKP1int(),b.getKP2int());
3631
3632 loc_grid.get(i).setGPUInsertBuffer(ite.nblocks(),ite.nthrs());
3633 loc_grid.get(i).initializeGPUInsertBuffer();
3634
3635 ite_gpu_dist<dim> itd = ite;
3636
3637 for (int j = 0 ; j < dim ; j++)
3638 {
3639 itd.origin.set_d(j,gdb_ext.get(i).origin.get(j));
3640 itd.start_base.set_d(j,0);
3641 }
3642
3643 CUDA_LAUNCH((grid_apply_functor),ite,loc_grid.get(i).toKernel(),itd,func_t(),args...);
3644
3645 it.nextGrid();
3646 }
3647 }
3648
3654 void removePoints(Box<dim,size_t> & box)
3655 {
3656 Box<dim,long int> box_i = box;
3657
3658 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3659 {
3660 Box<dim,long int> bx = gdb_ext.get(i).Dbox + gdb_ext.get(i).origin;
3661
3662 Box<dim,long int> bout;
3663 bool inte = bx.Intersect(box,bout);
3664 bout -= gdb_ext.get(i).origin;
3665
3666 if (inte == true)
3667 {
3668 loc_grid.get(i).copyRemoveReset();
3669 loc_grid.get(i).remove(bout);
3670 loc_grid.get(i).removePoints(v_cl.getgpuContext());
3671 }
3672 }
3673 }
3674
3678 template<unsigned int ... prp> void deviceToHost()
3679 {
3680 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3681 {
3682 loc_grid.get(i).template deviceToHost<prp ...>();
3683 }
3684 }
3685
3689 template<unsigned int ... prp> void hostToDevice()
3690 {
3691 for (size_t i = 0 ; i < loc_grid.size() ; i++)
3692 {
3693 loc_grid.get(i).template hostToDevice<prp ...>();
3694 }
3695 }
3696
3697#endif
3698
3699
3701 //\cond
3703 //\endcond
3704};
3705
3706
3707template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St> >
3709
3710template<unsigned int dim, typename St, typename T, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3712
3713template<unsigned int dim, typename St, typename T, typename devg, typename Memory = HeapMemory, typename Decomposition = CartDecomposition<dim,St>>
3715
3716#ifdef __NVCC__
3717template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3719
3720template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3722
3723template<unsigned int dim, typename St, typename T, typename Memory = CudaMemory, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte> >
3725#endif
3726
3727#endif
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition Box.hpp:556
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition Box.hpp:95
void zero()
Set p1 and p2 to 0.
Definition Box.hpp:970
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition Box.hpp:567
void magnify_fix_P1(T mg)
Magnify the box by a factor keeping fix the point P1.
Definition Box.hpp:907
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition Box.hpp:823
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition Box.hpp:1180
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
Point< dim, T > getP1() const
Get the point p1.
Definition Box.hpp:708
grid_key_dx< dim > getKP2() const
Get the point p12 as grid_key_dx.
Definition Box.hpp:669
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
grid_key_dx< dim > getKP1() const
Get the point p1 as grid_key_dx.
Definition Box.hpp:656
This class decompose a space into sub-sub-domains and distribute them across processors.
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.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition Point.hpp:172
This class represent an N-dimensional box.
Definition SpaceBox.hpp:27
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.
size_t getProcessingUnits()
Get the total number of processors.
gpu::ofp_context_t & getgpuContext(bool iw=true)
If nvidia cuda is activated return a gpu context.
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:450
bool SSendRecv(openfpm::vector< T > &send, S &recv, openfpm::vector< size_t > &prc_send, openfpm::vector< size_t > &prc_recv, openfpm::vector< size_t > &sz_recv, size_t opt=NONE)
Semantic Send and receive, send the data to processors and receive from the other processors.
Definition VCluster.hpp:797
Distributed linearized key.
This class is an helper for the communication of grid_dist_id.
void ghost_put_(Decomposition &dec, const openfpm::vector< ip_box_grid< dim > > &ig_box, const openfpm::vector< ep_box_grid< dim > > &eg_box, const openfpm::vector< i_lbox_grid< dim > > &loc_ig_box, const openfpm::vector< e_lbox_grid< dim > > &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims > > &gdb_ext, openfpm::vector< device_grid > &loc_grid, openfpm::vector< std::unordered_map< size_t, size_t > > &g_id_to_internal_ghost_box)
It merge the information in the ghost with the real information.
void ghost_get_(const openfpm::vector< ip_box_grid< dim > > &ig_box, const openfpm::vector< ep_box_grid< dim > > &eg_box, const openfpm::vector< i_lbox_grid< dim > > &loc_ig_box, const openfpm::vector< e_lbox_grid< dim > > &loc_eg_box, const openfpm::vector< GBoxes< device_grid::dims > > &gdb_ext, const openfpm::vector< e_box_multi< dim > > &eb_gid_list, bool use_bx_def, openfpm::vector< device_grid > &loc_grid, const grid_sm< dim, void > &ginfo, std::unordered_map< size_t, size_t > &g_id_to_external_ghost_box, size_t opt)
It fill the ghost part of the grids.
size_t opt
Receiving option.
Given the decomposition it create an iterator.
Given the decomposition it create an iterator.
This is a distributed grid.
const grid_sm< dim, void > & getGridInfoVoid() const
Get an object containing the grid informations without type.
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
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
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.
openfpm::vector< std::string > prp_names
properties names
const openfpm::vector< GBoxes< device_grid::dims > > & getLocalGridsInfo() const
It return the informations about the local grids.
void setBackgroundValue(T &bv)
set the background value
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.
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
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.
T value_type
value_type
bool init_e_g_box
Flag that indicate if the external ghost box has been initialized.
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)
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
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
grid_key_dx_iterator_sub< dim, no_stencil > get_loc_grid_iterator(size_t i)
Get the i sub-domain grid.
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.
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.
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 map(size_t opt=0)
It move all the grid parts that do not belong to the local processor to the respective processor.
grid_dist_id(Decomposition &&dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
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.
const Decomposition & getDecomposition() const
Get the object that store the information about the decomposition.
grid_dist_id(const Decomposition &dec, const size_t(&g_sz)[dim], const Ghost< dim, long int > &g)
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.
Memory memory_type
Type of Memory.
device_grid d_grid
Which kind of grid the structure store.
openfpm::vector< size_t > gdb_ext_markers
const grid_sm< dim, T > & getGridInfo() const
Get an object containing the grid informations.
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)
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.
Point< dim, St > getOffset(size_t i)
Get the point where it start the origin of the grid of the sub-domain i.
void flush_remove()
remove an element in the grid
static Ghost< dim, St > convert_ghost(const Ghost< dim, long int > &gd, const CellDecomposer_sm< dim, St, shift< dim, St > > &cd_sm)
Convert a ghost from grid point units into continus space.
bool init_i_g_box
Flag that indicate if the internal ghost box has been initialized.
const Box< dim, St > getDomain() const
Get the domain where the grid is defined.
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
device_grid & get_loc_grid(size_t i)
Get the i sub-domain grid.
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.
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
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.
void getGlobalGridsInfo(openfpm::vector< GBoxes< device_grid::dims > > &gdb_ext_global) const
It gathers the information about local grids for all of the processors.
Decomposition dec
Space Decomposition.
openfpm::vector< e_box_multi< dim > > eb_gid_list
device_grid device_grid_type
Type of device grid.
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 construct_link_up(self &grid_up, openfpm::vector< offset_mv< dim > > &mvof)
construct link between current and the level up
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.
Ghost< dim, long int > ghost_int
Ghost expansion.
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_dist_iterator< dim, device_grid, decltype(device_grid::type_of_iterator()), FIXED > getDomainGhostIterator() const
It return an iterator that span the grid domain + ghost part.
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &k) const
Convert a g_dist_key_dx into a global key.
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
grid_dist_iterator_sub< dim, device_grid > getSubDomainIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop) const
It return an iterator that span the grid domain only in the specified part.
const openfpm::vector< i_lbox_grid< dim > > & get_loc_ig_box()
Get the internal local ghost box.
void clear()
It delete all the points.
void construct_link_dw(self &grid_dw, openfpm::vector< offset_mv< dim > > &mvof)
construct link between current and the level down
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
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.
void tagBoundaries()
construct link between current and the level up
bool existPoint(const grid_dist_key_dx< dim, bg_key > &v1) const
Check if the point exist.
const openfpm::vector< std::string > & getPropNames()
Set the properties names.
size_t size() const
Return the total number of points in the grid.
Point< dim, St > getPos(const grid_dist_key_dx< dim, bg_key > &v1)
Get the reference of the selected element.
~grid_dist_id()
Destructor.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition using a resolution function.
const openfpm::vector< i_lbox_grid< dim > > & get_ig_box()
Get the internal ghost box.
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.
bool use_bx_def
Indicate if we have to use bx_def to define the grid.
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 Create(openfpm::vector< Box< dim, long int > > &bx_def, const Ghost< dim, long int > &g, bool use_bx_def)
Create the grids on memory.
Vcluster & v_cl
Communicator class.
openfpm::vector< i_lbox_grid< dim > > loc_ig_box
Local internal ghost boxes in grid units.
grid_dist_id_iterator_dec< Decomposition > getGridIterator()
void ghost_put()
It synchronize the ghost parts.
size_t getLocalDomainWithGhostSize() const
Get the total number of grid points with ghost for the calling processor.
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.
const CellDecomposer_sm< dim, St, shift< dim, St > > & getCellDecomposer() const
Return the cell decomposer.
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.
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.
void setBackgroundValue(const typename boost::mpl::at< typename T::type, boost::mpl::int_< p > >::type &bv)
set the background value
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.
auto insertFlush(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).template insertFlush(v1.getKey()))
insert an element in the grid
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
Point< dim, St > getSpacing()
Get the spacing on each dimension.
grid_dist_id(const Decomposition2 &dec, const size_t(&g_sz)[dim], const Ghost< dim, St > &ghost)
const device_grid & get_loc_grid(size_t i) const
Get the i sub-domain grid.
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.
openfpm::vector< device_grid > loc_grid
Local grids.
long int who()
It return the id of structure in the allocation list.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_global
Global gdb_ext.
grid_dist_id_iterator_dec< Decomposition, true > getGridGhostIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
Vcluster & getVC()
Get the Virtual Cluster machine.
openfpm::vector< size_t > recv_sz
Receiving size.
void check_domain(const Box< dim, St > &dom)
Check the domain is valid.
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.
void construct_link(self &grid_up, self &grid_dw)
construct link between levels
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.
grid_dist_id(const size_t(&g_sz)[dim], const Box< dim, St > &domain, const Ghost< dim, long int > &g, size_t opt=0)
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.
openfpm::vector< Box< dim, long int > > bx_def
Set of boxes that define where the grid is defined.
bool write_debug(std::string output)
Write all grids indigually.
openfpm::vector< HeapMemory > recv_mem_gg
Receiving buffer for particles ghost get.
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.
openfpm::vector< GBoxes< device_grid::dims > > gdb_ext_old
Extension of each old grid (old): Domain and ghost + domain.
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 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.
bool init_local_e_g_box
Indicate if the local external ghost box has been initialized.
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.
size_t getSub() const
Get the local grid.
base_key getKey() const
Get the key.
base_key & getKeyRef()
Get the reference 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.
size_t size()
Stub size.
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
Structure for stencil iterator.