OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
26template<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
242public:
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_ */
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
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition Box.hpp:567
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition Box.hpp:823
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
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])
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
This class represent an N-dimensional box.
Definition SpaceBox.hpp:27
structure that store and compute the internal and external local ghost box
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 ...
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(ie_loc_ghost< dim, T, layout_base2, Memory2 > &&ilg)
copy the ie_loc_ghost
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.
ie_loc_ghost(const ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
Constructor from another ie_loc_ghost.
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.
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.
ie_loc_ghost()
Default constructor.
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.
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.
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.
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(const ie_loc_ghost< dim, T, layout_base2, Memory2 > &ilg)
copy the ie_loc_ghost
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.
const comb< dim > & getLocalEGhostPos(size_t i, size_t j) const
Get the j external local ghost box for the local processor.
void reset()
Reset 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.
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.
void flush(openfpm::vector< Box_loc_sub< dim, T > > &sub_domains)
Flush the temporal added sub-domain to the sub-domain list.
const ::Box< dim, T > & getLocalEGhostBox(size_t i, size_t j) const
Get the j external local ghost box for the local processor.
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 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 ...
ie_loc_ghost< dim, T, layout_base, Memory > & operator=(const ie_loc_ghost< dim, T, layout_base, Memory > &ilg)
copy the ie_loc_ghost
void add_subdomain(const Box_loc_sub< dim, T > &bx)
add sub-domains to a temporal list
const ::Box< dim, T > & getLocalIGhostBox(size_t i, size_t j) const
Get the j internal local ghost box for the i sub-domain.
openfpm::vector< lBox_dom< dim, T > > & private_get_loc_ghost_box()
Get the internal loc_ghost_box.
This class store the adjacent processors and the adjacent sub_domains.
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
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