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