OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
ie_loc_ghost.hpp
1 /*
2  * ie_ghost.hpp
3  *
4  * Created on: Aug 8, 2015
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_
9 #define SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_
10 
11 #include "Space/Shape/Box.hpp"
12 #include "Space/Ghost.hpp"
13 #include "Space/SpaceBox.hpp"
14 #include "common.hpp"
15 #include "VTKWriter/VTKWriter.hpp"
16 #include "nn_processor.hpp"
17 
26 template<unsigned int dim, typename T, template <typename> class layout_base, typename Memory>
28 {
31 
34 
43  openfpm::vector<SpaceBox<dim,T>,Memory,layout_base> & sub_domains,
44  openfpm::vector<Box_loc_sub<dim,T>> & sub_domains_prc)
45  {
46  comb<dim> zero;
47  zero.zero();
48 
49  loc_ghost_box.resize(sub_domains.size());
50 
51  // For each sub-domain
52  for (size_t i = 0 ; i < sub_domains.size() ; i++)
53  {
54  SpaceBox<dim,T> sub_with_ghost = sub_domains.get(i);
55 
56  // enlarge the sub-domain with the ghost
57  sub_with_ghost.enlarge(ghost);
58 
59  // intersect with the other local sub-domains
60  for (size_t j = 0 ; j < sub_domains_prc.size() ; j++)
61  {
62  size_t rj = sub_domains_prc.get(j).sub;
63 
64  if (rj == i && sub_domains_prc.get(j).cmb == zero)
65  continue;
66 
67  ::Box<dim,T> bi;
68 
69  bool intersect = sub_with_ghost.Intersect(sub_domains_prc.get(j).bx,bi);
70 
71  if (intersect == true)
72  {
74  b.sub = rj;
75  b.bx = bi;
76  b.cmb = sub_domains_prc.get(j).cmb;
77 
78  // local external ghost box
79  loc_ghost_box.get(i).ebx.add(b);
80 
81  // search this box in the internal box of the sub-domain j
82  for (size_t k = 0; k < loc_ghost_box.get(rj).ibx.size() ; k++)
83  {
84  if (loc_ghost_box.get(rj).ibx.get(k).sub == i && loc_ghost_box.get(rj).ibx.get(k).cmb == sub_domains_prc.get(j).cmb.operator-())
85  {
86  loc_ghost_box.get(rj).ibx.get(k).k = loc_ghost_box.get(i).ebx.size()-1;
87  loc_ghost_box.get(i).ebx.last().k = k;
88  break;
89  }
90  }
91  }
92  }
93  }
94  }
95 
104  openfpm::vector<SpaceBox<dim,T>,Memory,layout_base> & sub_domains,
105  openfpm::vector<Box_loc_sub<dim,T>> & sub_domains_prc)
106  {
107  comb<dim> zero;
108  zero.zero();
109 
110  loc_ghost_box.resize(sub_domains.size());
111 
112  // For each sub-domain
113  for (size_t i = 0 ; i < sub_domains.size() ; i++)
114  {
115  // intersect with the others local sub-domains
116  for (size_t j = 0 ; j < sub_domains_prc.size() ; j++)
117  {
118  SpaceBox<dim,T> sub_with_ghost = sub_domains_prc.get(j).bx;
119  size_t rj = sub_domains_prc.get(j).sub;
120 
121  // Avoid to intersect the box with itself
122  if (rj == i && sub_domains_prc.get(j).cmb == zero)
123  continue;
124 
125  // enlarge the sub-domain with the ghost
126  sub_with_ghost.enlarge(ghost);
127 
128  ::Box<dim,T> bi;
129 
130  bool intersect = sub_with_ghost.Intersect(::SpaceBox<dim,T>(sub_domains.get(i)),bi);
131 
132  if (intersect == true)
133  {
135  b.sub = rj;
136  b.bx = bi;
137  b.k = -1;
138  b.cmb = sub_domains_prc.get(j).cmb;
139 
140  loc_ghost_box.get(i).ibx.add(b);
141  }
142  }
143  }
144  }
145 
154  void applyBC(openfpm::vector<Box_loc_sub<dim,T>> & sub_domains, const Box<dim,T> & domain, const Ghost<dim,T> & ghost, const size_t (&bc)[dim])
155  {
156  HyperCube<dim> hyp;
157 
158  // first we create boxes at the border of the domain used to detect the sub-domain
159  // that must be adjusted, each of this boxes define a shift in case of periodic boundary condition
160  for (long int i = dim-1 ; i >= 0 ; i--)
161  {
162  std::vector<comb<dim>> cmbs = hyp.getCombinations_R_bc(i,bc);
163 
164  for (size_t j = 0 ; j < cmbs.size() ; j++)
165  {
166  if (nn_prcs<dim,T,layout_base,Memory>::check_valid(cmbs[j],bc) == false)
167  continue;
168 
169  Box<dim,T> bp;
171 
172  for (size_t k = 0 ; k < dim ; k++)
173  {
174  switch (cmbs[j][k])
175  {
176  case 1:
177  bp.setLow(k,domain.getHigh(k)+ghost.getLow(k));
178  bp.setHigh(k,domain.getHigh(k));
179  shift.get(k) = -domain.getHigh(k)+domain.getLow(k);
180  break;
181  case 0:
182  bp.setLow(k,domain.getLow(k));
183  bp.setHigh(k,domain.getHigh(k));
184  shift.get(k) = 0;
185  break;
186  case (char)-1:
187  bp.setLow(k,domain.getLow(k));
188  bp.setHigh(k,ghost.getHigh(k));
189  shift.get(k) = domain.getHigh(k)-domain.getLow(k);
190  break;
191  }
192  }
193 
194  // Detect all the sub-domain involved, shift them and add to the list
195  // Detection is performed intersecting the sub-domains with the ghost
196  // parts near the domain borders
197  for (size_t k = 0 ; k < sub_domains.size() ; k++)
198  {
199  Box<dim,T> sub = sub_domains.get(k).bx;
200  Box<dim,T> b_int;
201 
202  if (sub.Intersect(bp,b_int) == true)
203  {
204  sub += shift;
205  add_subdomain(Box_loc_sub<dim,T>(sub,k,cmbs[j]));
206  }
207  }
208  }
209  }
210 
211  flush(sub_domains);
212  }
213 
214 
215 
221  inline void add_subdomain(const Box_loc_sub<dim,T> & bx)
222  {
223  sub_domains_tmp.add(bx);
224  }
225 
233  {
234  for (size_t i = 0 ; i < sub_domains_tmp.size() ; i++)
235  {
236  sub_domains.add(sub_domains_tmp.get(i));
237  }
238 
239  sub_domains_tmp.clear();
240  }
241 
242 public:
243 
252  void create(openfpm::vector<SpaceBox<dim,T>,Memory,layout_base> & sub_domains, Box<dim,T> & domain , Ghost<dim,T> & ghost , const size_t (&bc)[dim] )
253  {
254  // It will store local sub-domains + borders
255  openfpm::vector<Box_loc_sub<dim,T>> sub_domains_prc;
256 
257  comb<dim> zero;
258  zero.zero();
259 
260  // Copy sub_domains into sub_domains_prc
261  for (size_t i = 0 ; i < sub_domains.size() ; i++)
262  {
263  Box_loc_sub<dim,T> bls(SpaceBox<dim,T>(sub_domains.get(i)),i,zero);
264  sub_domains_prc.add(bls);
265  sub_domains_prc.last().sub = i;
266  }
267 
268  applyBC(sub_domains_prc,domain,ghost,bc);
269 
270  create_loc_ghost_ibox(ghost,sub_domains,sub_domains_prc);
271  create_loc_ghost_ebox(ghost,sub_domains,sub_domains_prc);
272  }
273 
276 
279  {
280  this->operator=(ilg);
281  };
282 
285  {
286  this->operator=(ilg);
287  }
288 
297  {
299  return *this;
300  }
301 
310  {
311  loc_ghost_box.swap(ilg.loc_ghost_box);
312  return *this;
313  }
314 
322  template<template <typename> class layout_base2, typename Memory2>
324  {
326  return *this;
327  }
328 
336  template<template <typename> class layout_base2, typename Memory2>
338  {
339  loc_ghost_box.swap(ilg.private_get_loc_ghost_box());
340  return *this;
341  }
342 
349  {
350  return loc_ghost_box;
351  }
352 
359  inline size_t getNLocalSub()
360  {
361  return loc_ghost_box.size();
362  }
363 
371  inline size_t getLocalNEGhost(size_t id)
372  {
373  return loc_ghost_box.get(id).ebx.size();
374  }
375 
383  inline size_t getLocalNIGhost(size_t id)
384  {
385  return loc_ghost_box.get(id).ibx.size();
386  }
387 
400  inline size_t getLocalIGhostE(size_t i, size_t j)
401  {
402  return loc_ghost_box.get(i).ibx.get(j).k;
403  }
404 
420  inline const ::Box<dim,T> & getLocalIGhostBox(size_t i, size_t j) const
421  {
422  return loc_ghost_box.get(i).ibx.get(j).bx;
423  }
424 
475  inline const comb<dim> & getLocalIGhostPos(size_t i, size_t j) const
476  {
477  return loc_ghost_box.get(i).ibx.get(j).cmb;
478  }
479 
487  inline const ::Box<dim,T> & getLocalEGhostBox(size_t i, size_t j) const
488  {
489  return loc_ghost_box.get(i).ebx.get(j).bx;
490  }
491 
499  inline const comb<dim> & getLocalEGhostPos(size_t i, size_t j) const
500  {
501  return loc_ghost_box.get(i).ebx.get(j).cmb;
502  }
503 
514  inline size_t getLocalIGhostSub(size_t i, size_t k) const
515  {
516  return loc_ghost_box.get(i).ibx.get(k).sub;
517  }
518 
529  inline size_t getLocalEGhostSub(size_t i, size_t k) const
530  {
531  return loc_ghost_box.get(i).ebx.get(k).sub;
532  }
533 
549  bool write(std::string output, size_t p_id) const
550  {
551  // Copy the Box_sub_k into a vector of boxes
553 
554  for (size_t p = 0 ; p < loc_ghost_box.size() ; p++)
555  {
556  vv5.add();
557  for (size_t i = 0 ; i < loc_ghost_box.get(p).ibx.size() ; i++)
558  vv5.last().add(loc_ghost_box.get(p).ibx.get(i).bx);
559  }
560 
562  VTKWriter<openfpm::vector<Box<dim,T>>,VECTOR_BOX> vtk_box5;
563  for (size_t p = 0 ; p < vv5.size() ; p++)
564  {
565  vtk_box5.add(vv5.get(p));
566  }
567  vtk_box5.write(output + std::string("local_internal_ghost_") + std::to_string(p_id) + std::string(".vtk"));
568 
569  // Copy the Box_sub_k into a vector of boxes
571 
572  for (size_t p = 0 ; p < loc_ghost_box.size() ; p++)
573  {
574  vv6.add();
575  for (size_t i = 0 ; i < loc_ghost_box.get(p).ebx.size() ; i++)
576  vv6.last().add(loc_ghost_box.get(p).ebx.get(i).bx);
577  }
578 
580  VTKWriter<openfpm::vector<Box<dim,T>>,VECTOR_BOX> vtk_box6;
581  for (size_t p = 0 ; p < vv6.size() ; p++)
582  {
583  vtk_box6.add(vv6.get(p));
584  }
585  vtk_box6.write(output + std::string("local_external_ghost_") + std::to_string(p_id) + std::string(".vtk"));
586 
587  return true;
588  }
589 
597  bool check_consistency(size_t n_sub)
598  {
600  for (size_t i = 0 ; i < loc_ghost_box.size() ; i++)
601  {
602  for (size_t j = 0 ; j < loc_ghost_box.get(i).ibx.size() ; j++)
603  {
604  if (loc_ghost_box.get(i).ibx.get(j).k == -1)
605  {
606  std::cout << __FILE__ << ":" << __LINE__ << " Error: inconsistent decomposition no ibx link" << "\n";
607  return false;
608  }
609 
610  size_t k = loc_ghost_box.get(i).ibx.get(j).k;
611  size_t sub = loc_ghost_box.get(i).ibx.get(j).sub;
612 
613  if (loc_ghost_box.get(sub).ebx.get(k).k != (long int)j)
614  {
615  std::cout << __FILE__ << ":" << __LINE__ << " Error: inconsistent link between an external ghost box and an internal ghost box" << "\n";
616  return false;
617  }
618  }
619  }
620 
621  return true;
622  }
623 
632  {
633  if (ilg.loc_ghost_box.size() != loc_ghost_box.size())
634  return false;
635 
636  // Explore all the subdomains
637  for (size_t i = 0 ; i < loc_ghost_box.size() ; i++)
638  {
639  if (getLocalNIGhost(i) != ilg.getLocalNIGhost(i))
640  return false;
641 
642  if (getLocalNEGhost(i) != ilg.getLocalNEGhost(i))
643  return false;
644 
645  for (size_t j = 0 ; j < getLocalNIGhost(i) ; j++)
646  {
647  if (getLocalIGhostE(i,j) != ilg.getLocalIGhostE(i,j))
648  return false;
649  if (getLocalIGhostBox(i,j) != ilg.getLocalIGhostBox(i,j))
650  return false;
651  if (getLocalIGhostSub(i,j) != ilg.getLocalIGhostSub(i,j))
652  return false;
653  }
654  for (size_t j = 0 ; j < getLocalNEGhost(i) ; j++)
655  {
656  if (getLocalEGhostBox(i,j) != ilg.getLocalEGhostBox(i,j))
657  return false;
658  if (getLocalEGhostSub(i,j) != ilg.getLocalEGhostSub(i,j))
659  return false;
660  }
661 
662  }
663 
664  return true;
665  }
666 
667 
668 
679  {
680  return true;
681  }
682 
686  void reset()
687  {
688  loc_ghost_box.clear();
689  sub_domains_tmp.clear();
690  }
691 };
692 
693 
694 #endif /* SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_ */
size_t getLocalNEGhost(size_t id)
Get the number of external local ghost box for each sub-domain.
const ::Box< dim, T > & getLocalEGhostBox(size_t i, size_t j) const
Get the j external local ghost box for the local processor.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(ie_loc_ghost< dim, T, layout_base, Memory > &&ilg)
copy the ie_loc_ghost
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(const ie_loc_ghost< dim, T, layout_base2, Memory2 > &ilg)
copy the ie_loc_ghost
size_t getLocalEGhostSub(size_t i, size_t k) const
Considering that sub-domains has N external local ghost box identified with the 0 <= k < N that come ...
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
ie_loc_ghost(ie_loc_ghost< dim, T, layout_base, Memory > &&ilg)
Constructor from temporal ie_loc_ghost.
void create_loc_ghost_ebox(Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, openfpm::vector< Box_loc_sub< dim, T >> &sub_domains_prc)
Create the external local ghost boxes.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
bool is_equal(ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
Check if the ie_loc_ghosts contain the same information.
bool write(std::string output, size_t p_id) const
Write the decomposition as VTK file.
openfpm::vector< Box_loc_sub< dim, T > > sub_domains_tmp
temporal added sub-domains
void create(openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, Box< dim, T > &domain, Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Create external and internal local ghosts.
for each sub-domain box sub contain the real the sub-domain id
Definition: common.hpp:45
void create_loc_ghost_ibox(Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, openfpm::vector< Box_loc_sub< dim, T >> &sub_domains_prc)
Create the internal local ghost boxes.
ie_loc_ghost(const ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
Constructor from another ie_loc_ghost.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
static std::vector< comb< dim > > getCombinations_R_bc(size_t d, const size_t(&bc)[dim])
Definition: HyperCube.hpp:151
size_t size()
Stub size.
Definition: map_vector.hpp:211
bool is_equal_ng(ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
Check if the ie_loc_ghosts contain the same information with the exception of the ghost part.
const comb< dim > & getLocalEGhostPos(size_t i, size_t j) const
Get the j external local ghost box for the local processor.
Definition: Ghost.hpp:39
Particular case for local internal ghost boxes.
Definition: common.hpp:118
const comb< dim > & getLocalIGhostPos(size_t i, size_t j) const
Get the j internal local ghost box boundary position for the i sub-domain of the local processor.
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
size_t getLocalIGhostE(size_t i, size_t j)
For the sub-domain i intersected with a surrounding sub-domain enlarged j. Produce a internal ghost b...
openfpm::vector< lBox_dom< dim, T > > & private_get_loc_ghost_box()
Get the internal loc_ghost_box.
void reset()
Reset the ie_loc_ghost.
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(ie_loc_ghost< dim, T, layout_base2, Memory2 > &&ilg)
copy the ie_loc_ghost
openfpm::vector< lBox_dom< dim, T > > loc_ghost_box
It contain the calculated local ghost boxes.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:823
void add_subdomain(const Box_loc_sub< dim, T > &bx)
add sub-domains to a temporal list
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
size_t getLocalIGhostSub(size_t i, size_t k) const
Considering that sub-domains has N internal local ghost box identified with the 0 <= k < N that come ...
void flush(openfpm::vector< Box_loc_sub< dim, T >> &sub_domains)
Flush the temporal added sub-domain to the sub-domain list.
void zero()
Set all the elements to zero.
Definition: comb.hpp:83
This class represent an N-dimensional box.
Definition: Box.hpp:60
size_t getNLocalSub()
Get the number of local ghost boxes.
bool check_consistency(size_t n_sub)
function to check the consistency of the information of the decomposition
void applyBC(openfpm::vector< Box_loc_sub< dim, T >> &sub_domains, const Box< dim, T > &domain, const Ghost< dim, T > &ghost, const size_t(&bc)[dim])
In case of periodic boundary conditions we replicate the sub-domains at the border.
structure that store and compute the internal and external local ghost box
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:95
ie_loc_ghost()
Default constructor.
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(const ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
copy the ie_loc_ghost
This class calculate elements of the hyper-cube.
Definition: HyperCube.hpp:57
size_t getLocalNIGhost(size_t id)
Get the number of internal local ghost box for each sub-domain.
const ::Box< dim, T > & getLocalIGhostBox(size_t i, size_t j) const
Get the j internal local ghost box for the i sub-domain.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
This class store the adjacent processors and the adjacent sub_domains.