OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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>
28 {
31 
34 
43  openfpm::vector<SpaceBox<dim,T>> & 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>> & 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>::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 -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>> & 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 
321  inline size_t getNLocalSub()
322  {
323  return loc_ghost_box.size();
324  }
325 
333  inline size_t getLocalNEGhost(size_t id)
334  {
335  return loc_ghost_box.get(id).ebx.size();
336  }
337 
345  inline size_t getLocalNIGhost(size_t id)
346  {
347  return loc_ghost_box.get(id).ibx.size();
348  }
349 
362  inline size_t getLocalIGhostE(size_t i, size_t j)
363  {
364  return loc_ghost_box.get(i).ibx.get(j).k;
365  }
366 
382  inline const ::Box<dim,T> & getLocalIGhostBox(size_t i, size_t j) const
383  {
384  return loc_ghost_box.get(i).ibx.get(j).bx;
385  }
386 
437  inline const comb<dim> & getLocalIGhostPos(size_t i, size_t j) const
438  {
439  return loc_ghost_box.get(i).ibx.get(j).cmb;
440  }
441 
449  inline const ::Box<dim,T> & getLocalEGhostBox(size_t i, size_t j) const
450  {
451  return loc_ghost_box.get(i).ebx.get(j).bx;
452  }
453 
461  inline const comb<dim> & getLocalEGhostPos(size_t i, size_t j) const
462  {
463  return loc_ghost_box.get(i).ebx.get(j).cmb;
464  }
465 
476  inline size_t getLocalIGhostSub(size_t i, size_t k) const
477  {
478  return loc_ghost_box.get(i).ibx.get(k).sub;
479  }
480 
491  inline size_t getLocalEGhostSub(size_t i, size_t k) const
492  {
493  return loc_ghost_box.get(i).ebx.get(k).sub;
494  }
495 
511  bool write(std::string output, size_t p_id) const
512  {
513  // Copy the Box_sub_k into a vector of boxes
515 
516  for (size_t p = 0 ; p < loc_ghost_box.size() ; p++)
517  {
518  vv5.add();
519  for (size_t i = 0 ; i < loc_ghost_box.get(p).ibx.size() ; i++)
520  vv5.last().add(loc_ghost_box.get(p).ibx.get(i).bx);
521  }
522 
524  VTKWriter<openfpm::vector<Box<dim,T>>,VECTOR_BOX> vtk_box5;
525  for (size_t p = 0 ; p < vv5.size() ; p++)
526  {
527  vtk_box5.add(vv5.get(p));
528  }
529  vtk_box5.write(output + std::string("local_internal_ghost_") + std::to_string(p_id) + std::string(".vtk"));
530 
531  // Copy the Box_sub_k into a vector of boxes
533 
534  for (size_t p = 0 ; p < loc_ghost_box.size() ; p++)
535  {
536  vv6.add();
537  for (size_t i = 0 ; i < loc_ghost_box.get(p).ebx.size() ; i++)
538  vv6.last().add(loc_ghost_box.get(p).ebx.get(i).bx);
539  }
540 
542  VTKWriter<openfpm::vector<Box<dim,T>>,VECTOR_BOX> vtk_box6;
543  for (size_t p = 0 ; p < vv6.size() ; p++)
544  {
545  vtk_box6.add(vv6.get(p));
546  }
547  vtk_box6.write(output + std::string("local_external_ghost_") + std::to_string(p_id) + std::string(".vtk"));
548 
549  return true;
550  }
551 
559  bool check_consistency(size_t n_sub)
560  {
562  for (size_t i = 0 ; i < loc_ghost_box.size() ; i++)
563  {
564  for (size_t j = 0 ; j < loc_ghost_box.get(i).ibx.size() ; j++)
565  {
566  if (loc_ghost_box.get(i).ibx.get(j).k == -1)
567  {
568  std::cout << __FILE__ << ":" << __LINE__ << " Error: inconsistent decomposition no ibx link" << "\n";
569  return false;
570  }
571 
572  size_t k = loc_ghost_box.get(i).ibx.get(j).k;
573  size_t sub = loc_ghost_box.get(i).ibx.get(j).sub;
574 
575  if (loc_ghost_box.get(sub).ebx.get(k).k != (long int)j)
576  {
577  std::cout << __FILE__ << ":" << __LINE__ << " Error: inconsistent link between an external ghost box and an internal ghost box" << "\n";
578  return false;
579  }
580  }
581  }
582 
583  return true;
584  }
585 
594  {
595  if (ilg.loc_ghost_box.size() != loc_ghost_box.size())
596  return false;
597 
598  // Explore all the subdomains
599  for (size_t i = 0 ; i < loc_ghost_box.size() ; i++)
600  {
601  if (getLocalNIGhost(i) != ilg.getLocalNIGhost(i))
602  return false;
603 
604  if (getLocalNEGhost(i) != ilg.getLocalNEGhost(i))
605  return false;
606 
607  for (size_t j = 0 ; j < getLocalNIGhost(i) ; j++)
608  {
609  if (getLocalIGhostE(i,j) != ilg.getLocalIGhostE(i,j))
610  return false;
611  if (getLocalIGhostBox(i,j) != ilg.getLocalIGhostBox(i,j))
612  return false;
613  if (getLocalIGhostSub(i,j) != ilg.getLocalIGhostSub(i,j))
614  return false;
615  }
616  for (size_t j = 0 ; j < getLocalNEGhost(i) ; j++)
617  {
618  if (getLocalEGhostBox(i,j) != ilg.getLocalEGhostBox(i,j))
619  return false;
620  if (getLocalEGhostSub(i,j) != ilg.getLocalEGhostSub(i,j))
621  return false;
622  }
623 
624  }
625 
626  return true;
627  }
628 
629 
630 
641  {
642  return true;
643  }
644 
648  void reset()
649  {
650  loc_ghost_box.clear();
651  sub_domains_tmp.clear();
652  }
653 };
654 
655 
656 #endif /* SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_ */
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
size_t sub
Domain id.
Definition: common.hpp:102
openfpm::vector< Box_loc_sub< dim, T > > sub_domains_tmp
temporal added sub-domains
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 > > loc_ghost_box
It contain the calculated local ghost boxes.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
void add_subdomain(const Box_loc_sub< dim, T > &bx)
add sub-domains to a temporal list
void flush(openfpm::vector< Box_loc_sub< dim, T >> &sub_domains)
Flush the temporal added sub-domain to the sub-domain list.
ie_loc_ghost< dim, T > & operator=(ie_loc_ghost< dim, T > &&ilg)
copy the ie_loc_ghost
Box< dim, T > bx
extension of this local internal ghost box
Definition: common.hpp:99
for each sub-domain box sub contain the real the sub-domain id
Definition: common.hpp:26
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
bool check_consistency(size_t n_sub)
function to check the consistency of the information of the decomposition
size_t size()
Stub size.
Definition: map_vector.hpp:70
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
static std::vector< comb< dim > > getCombinations_R_bc(size_t d, const size_t(&bc)[dim])
Definition: HyperCube.hpp:151
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.
Definition: Ghost.hpp:39
Particular case for local internal ghost boxes.
Definition: common.hpp:96
void reset()
Reset the ie_loc_ghost.
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...
bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:88
size_t getNLocalSub()
Get the number of local sub-domains.
void create_loc_ghost_ibox(Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >> &sub_domains, openfpm::vector< Box_loc_sub< dim, T >> &sub_domains_prc)
Create the internal local ghost boxes.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:700
void create(openfpm::vector< SpaceBox< dim, T >> &sub_domains, Box< dim, T > &domain, Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Create external and internal local ghosts.
size_t getLocalIGhostE(size_t i, size_t j)
For the sub-domain i intersected with a surrounding sub-domain enlarged. Produce a internal ghost box...
ie_loc_ghost(ie_loc_ghost< dim, T > &&ilg)
Constructor from temporal ie_loc_ghost.
ie_loc_ghost()
Default constructor.
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
const comb< dim > & getLocalEGhostPos(size_t i, size_t j) const
Get the j external local ghost box for the local processor.
bool is_equal(ie_loc_ghost< dim, T > &ilg)
Check if the ie_loc_ghosts contain the same information.
void zero()
Set all the elements to zero.
Definition: comb.hpp:83
This class represent an N-dimensional box.
Definition: Box.hpp:56
bool is_equal_ng(ie_loc_ghost< dim, T > &ilg)
Check if the ie_loc_ghosts contain the same information with the exception of the ghost part...
bool write(std::string output, size_t p_id) const
Write the decomposition as VTK file.
comb< dim > cmb
Where this sub_domain live.
Definition: common.hpp:105
long int k
k
Definition: common.hpp:108
const ::Box< dim, T > & getLocalIGhostBox(size_t i, size_t j) const
Get the j internal local ghost box for the i sub-domain.
structure that store and compute the internal and external local ghost box
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 ...
This class calculate elements of the hyper-cube.
Definition: HyperCube.hpp:57
ie_loc_ghost< dim, T > & operator=(const ie_loc_ghost< dim, T > &ilg)
copy the ie_loc_ghost
size_t getLocalNIGhost(size_t id)
Get the number of internal local ghost box for each sub-domain.
ie_loc_ghost(const ie_loc_ghost< dim, T > &ilg)
Constructor from another ie_loc_ghost.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
void create_loc_ghost_ebox(Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >> &sub_domains, openfpm::vector< Box_loc_sub< dim, T >> &sub_domains_prc)
Create the external local ghost boxes.
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.
This class store the adjacent processors and the adjacent sub_domains.