OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
grid_dist_util.hpp
1 /*
2  * grid_dist_util.hpp
3  *
4  * Created on: Jan 28, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_GRID_GRID_DIST_UTIL_HPP_
9 #define SRC_GRID_GRID_DIST_UTIL_HPP_
10 
11 #include "NN/CellList/CellDecomposer.hpp"
12 #include "Decomposition/common.hpp"
13 
22 template<unsigned int dim> void getCellDecomposerPar(size_t (& c_g)[dim], const size_t (& g_sz)[dim], const size_t (& bc)[dim])
23 {
24  for (size_t i = 0 ; i < dim ; i++)
25  {
26  if (bc[i] == NON_PERIODIC)
27  c_g[i] = (g_sz[i]-1 > 0)?(g_sz[i]-1):1;
28  else
29  c_g[i] = g_sz[i];
30  }
31 }
32 
33 
41 template<unsigned int dim> periodicity<dim> create_non_periodic()
42 {
44 
45  for(size_t i = 0 ; i < dim ; i++)
46  p.bc[i] = NON_PERIODIC;
47 
48  return p;
49 }
50 
51 template<unsigned int dim>
52 size_t get_gdb_ext(const openfpm::vector<GBoxes<dim>> & gdb_ext, size_t start , size_t stop, size_t k)
53 {
54  for (size_t i = start ; i < stop ; i++)
55  {
56  if (gdb_ext.get(i).k == k)
57  {return i;}
58  }
59 
60  // not found
61  return (size_t)-1;
62 }
63 
73 template<unsigned int dim>
74 void add_to_gdb_ext(openfpm::vector<GBoxes<dim>> & gdb_ext, size_t k, Box<dim,long int> & sp_t, Box<dim,long int> & sp_tg)
75 {
76  // Add gdb_ext
77  gdb_ext.add();
78 
80  gdb_ext.last().origin = sp_tg.getP1();
81 
82  // save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning)
83  // and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate
84  gdb_ext.last().Dbox = sp_t;
85  gdb_ext.last().Dbox -= sp_tg.getP1();
86 
87  gdb_ext.last().GDbox = sp_tg;
88  gdb_ext.last().GDbox -= sp_tg.getP1();
89 
90  gdb_ext.last().k = k;
91 }
92 
103 template<int dim, typename Decomposition>
104 inline void create_gdb_ext(openfpm::vector<GBoxes<Decomposition::dims>> & gdb_ext,
105  openfpm::vector<size_t> & gdb_ext_markers,
106  Decomposition & dec,
107  CellDecomposer_sm<Decomposition::dims,typename Decomposition::stype,shift<dim,typename Decomposition::stype>> & cd_sm,
110  bool use_bx_def)
111 {
112  gdb_ext.clear();
113  gdb_ext_markers.clear();
114 
115  // Get the number of local grid needed
116  size_t n_grid = dec.getNSubDomain();
117 
118  // Allocate the grids
119  for (size_t i = 0 ; i < n_grid ; i++)
120  {
121  gdb_ext_markers.add(gdb_ext.size());
122 
123  // Get the local sub-domain (Grid conversion must be done with the domain P1 equivalent to 0.0)
124  // consider that the sub-domain with point P1 equivalent to the domain P1 is a (0,0,0) in grid unit
126  SpaceBox<Decomposition::dims, typename Decomposition::stype> sp_g = dec.getSubDomainWithGhost(i);
127 
128  // Because of round off we expand for safety the ghost area
129  // std::nextafter return the next bigger or smaller representable floating
130  // point number
131  for (size_t i = 0 ; i < Decomposition::dims ; i++)
132  {
133  sp_g.setLow(i,std::nextafter(sp_g.getLow(i),sp_g.getLow(i) - 1.0));
134  sp_g.setHigh(i,std::nextafter(sp_g.getHigh(i),sp_g.getHigh(i) + 1.0));
135  }
136 
137  // Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
138  SpaceBox<Decomposition::dims,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp,dec.periodicity());
139  SpaceBox<Decomposition::dims,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g,dec.periodicity());
140 
141  for (size_t i = 0 ; i < Decomposition::dims ; i++)
142  {
143  if (sp_t.getLow(i) < sp_tg.getLow(i))
144  {sp_tg.setLow(i,sp_t.getLow(i));}
145  if (sp_t.getHigh(i) > sp_tg.getHigh(i))
146  {sp_tg.setHigh(i,sp_t.getHigh(i));}
147  }
148 
149  if (use_bx_def == true)
150  {
151  // intersect the sub-domain with all the boxes
152 
153  for (size_t k = 0 ; k < bx_create.size() ; k++)
154  {
156 
157  if (sp_t.Intersect(bx_create.get(k),inte) == true)
158  {
159  // Ok we have a sub-domain now we have to create the ghost part.
160  // The ghost part is created converting the bx_def into a continuous
161  // box expanding this box by the ghost and intersecting this box
162  // with the sub-domain. This is one way to get a ghost area consistent
163  // with the construction of the external and internal ghost boxes,
164  // always calculated in continuous from the decomposition.
165  //
166 
168  Box<Decomposition::dims,typename Decomposition::stype> bx_wg = cd_sm.convertCellUnitsIntoDomainSpaceMiddle(bx_create.get(k));
169  bx_wg.enlarge(dec.getGhost());
170  bx_wg.Intersect(sp_g,output);
171 
173  SpaceBox<Decomposition::dims,long int> sp_tg2 = cd_sm.convertDomainSpaceIntoGridUnits(output,dec.periodicity());
174 
175  add_to_gdb_ext(gdb_ext,k,sp_t2,sp_tg2);
176  }
177  }
178  }
179  else
180  {
181  add_to_gdb_ext(gdb_ext,0,sp_t,sp_tg);
182  }
183  }
184 
185  gdb_ext_markers.add(gdb_ext.size());
186 }
187 
200 template<int dim, typename Decomposition>
201 inline void create_gdb_ext(openfpm::vector<GBoxes<dim>> & gdb_ext,
202  Decomposition & dec,
203  const size_t (& sz)[dim],
205  typename Decomposition::stype (& spacing)[dim])
206 {
207  // Create the cell decomposer
208  CellDecomposer_sm<Decomposition::dims,typename Decomposition::stype, shift<Decomposition::dims,typename Decomposition::stype>> cd_sm;
209 
210  size_t cdp[dim];
211 
212  // Get the parameters to create a Cell-decomposer
213  getCellDecomposerPar<Decomposition::dims>(cdp,sz,dec.periodicity());
214 
215  // Careful cd_sm require the number of cell
216  cd_sm.setDimensions(domain,cdp,0);
217 
218  // create an empty vector of boxes
221 
224  create_gdb_ext<dim,Decomposition>(gdb_ext,unused,dec,cd_sm,empty,zero,false);
225 
226  // fill the spacing
227  for (size_t i = 0 ; i < dim ; i++)
228  {spacing[i] = cd_sm.getCellBox().getP2()[i];}
229 }
230 
235 template <unsigned int dim> struct e_box_id
236 {
239 
242 
245 
248 
250  size_t g_id;
251 
253  size_t sub;
254 };
255 
264 template<unsigned int dim, typename T, typename idT>
265 Box<dim,long int> flip_box(const Box<dim,idT> & box, const comb<dim> & cmb, const grid_sm<dim,T> & ginfo)
266 {
267  Box<dim,long int> flp;
268 
269  for (size_t i = 0 ; i < dim; i++)
270  {
271  if (cmb[i] == 0)
272  {
273  flp.setLow(i,box.getLow(i));
274  flp.setHigh(i,box.getHigh(i));
275  }
276  else if (cmb[i] == 1)
277  {
278  flp.setLow(i,box.getLow(i) + ginfo.size(i));
279  flp.setHigh(i,box.getHigh(i) + ginfo.size(i));
280  }
281  else if (cmb[i] == -1)
282  {
283  flp.setLow(i,box.getLow(i) - ginfo.size(i));
284  flp.setHigh(i,box.getHigh(i) - ginfo.size(i));
285  }
286  }
287 
288  return flp;
289 }
290 
302 template<unsigned int dim>
303 inline size_t convert_to_gdb_ext(size_t sub_id,
304  size_t def_id,
305  openfpm::vector<GBoxes<dim>> & gdb_ext,
306  openfpm::vector<size_t> & gdb_ext_markers)
307 {
308  size_t start = gdb_ext_markers.get(sub_id);
309  size_t stop = gdb_ext_markers.get(sub_id+1);
310  return get_gdb_ext(gdb_ext,start,stop,def_id);
311 }
312 
317 template <unsigned int dim> struct e_lbox_id
318 {
321 
323  bool initialized = false;
324 
326  size_t sub;
327 
330  size_t sub_gdb_ext;
331 
333  size_t k;
334 
337 };
338 
339 
351 template<unsigned int dim> inline void add_loc_eg_box(size_t le_sub,
352  size_t se,
353  size_t j,
354  size_t k,
356  const Box<dim,long int> & ebox,
357  comb<dim> & cmb)
358 {
359  bid.add();
360 
361  bid.last().ebox = ebox;
362 
363  bid.last().sub = se;
364  bid.last().sub_gdb_ext = k;
365 
366  bid.last().cmb = cmb;
367  bid.last().k = j;
368  bid.last().initialized = true;
369 }
370 
382 template<unsigned int dim> inline void add_eg_box(size_t k,
383  const comb<dim> & cmb,
384  const Box<dim,long int> & output,
385  size_t g_id,
386  const Point<dim,long int> & origin,
387  const Point<dim,long int> & p1,
389 {
390  // link
391 
392  size_t sub_id = k;
393 
394  e_box_id<dim> bid_t;
395  bid_t.sub = sub_id;
396  bid_t.cmb = cmb;
397  bid_t.cmb.sign_flip();
398  ::Box<dim,long int> ib = output;
399  bid_t.g_e_box = ib;
400  bid_t.g_id = g_id;
401 
402  // Translate in local coordinate for gdb_ext
403  Box<dim,long int> tb = ib;
404  tb -= origin;
405  bid_t.l_e_box = tb;
406 
407  // Translate in local coordinates for the received box
408  Box<dim,long int> tbr = ib;
409  bid_t.lr_e_box = tbr;
410 
411  bid.add(bid_t);
412 }
413 
418 template<unsigned int dim>
420 {
422  size_t id;
423 
426 };
427 
437 template<unsigned int dim>
438 void bx_intersect(openfpm::vector<Box<dim,long int>> & bx_def,
439  bool use_bx_def,
440  Box<dim,long int> & bx,
442 {
443  result.clear();
444 
445  if (use_bx_def == false)
446  {
447  result_box<dim> tmp;
448  tmp.bx = bx;
449  tmp.id = 0;
450 
451  result.add(tmp);
452  return;
453  }
454 
455  for (size_t i = 0 ; i < bx_def.size() ; i++)
456  {
457  result_box<dim> inte;
458  if (bx.Intersect(bx_def.get(i),inte.bx))
459  {
460  inte.id = i;
461  result.add(inte);
462  }
463  }
464 }
465 
469 template<unsigned int dim> struct i_box_id
470 {
473 
475  size_t g_id;
476 
478  size_t r_sub;
479 
482 
483 
484 
486  size_t sub;
487 };
488 
493 template<unsigned int dim>
494 struct ibox_send
495 {
497  size_t gid;
498 
501 };
502 
503 
504 
509 template<unsigned int dim> struct i_lbox_id
510 {
513 
517  size_t sub;
518 
520  size_t sub_gdb_ext;
521 
524 
527 };
528 
529 
535 template<unsigned int dim>
537 {
541 
544  size_t full_match;
545 
548  size_t e_id;
549 };
550 
551 
555 template <unsigned int dim> struct ip_box_grid
556 {
557  // ghost in grid units
559 
561  size_t prc;
562 };
563 
567 template <unsigned int dim> struct i_lbox_grid
568 {
569  // ghost in grid units
571 };
572 
576 template <unsigned int dim>struct ep_box_grid
577 {
578  // ghost in grid units
580 
582  size_t prc;
583 
585  size_t recv_pnt;
586 
588  size_t n_r_box;
589 };
590 
594 template <unsigned int dim> struct e_lbox_grid
595 {
596  // ghost in grid units
598 };
599 
600 
601 #endif /* SRC_GRID_GRID_DIST_UTIL_HPP_ */
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
comb< dim > cmb
Sector position of the external ghost.
openfpm::vector< size_t > k
external ghost box linked to this internal ghost box
set of internal ghost box to send
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
local Internal ghost box
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:637
size_t sub
sub_id in which sub-domain this box live
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
size_t recv_pnt
total number of received points
it store an internal ghost box, the linked external ghost box and the sub-domain from where it come f...
size_t g_id
id
For each external ghost id, it contain a set of sub-domain at which this external box is linked.
Per-processor Internal ghost box.
openfpm::vector< size_t > eb_list
size_t sub
sub
::Box< dim, long int > box
Box.
comb< dim > cmb
Sector where it live the linked external ghost box.
size_t prc
processor id
size_t k
external ghost box linked to this internal ghost box
Definition: Ghost.hpp:39
size_t g_id
Id.
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
It store the information about the local external ghost box.
This structure store the Box that define the domain inside the Ghost + domain box.
Definition: GBoxes.hpp:39
This class define the domain decomposition interface.
bool initialized
Has this external ghost box initialized.
size_t gid
global id
it store a box, its unique id and the sub-domain from where it come from
Box< dim, long int > bx
valid result of the itersection
__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
::Box< dim, long int > ebox
Box defining the external ghost box in local coordinates.
size_t sub_gdb_ext
to which gdb_ext this internal ghost box is linked with
comb< dim > cmb
combination
size_t sub_gdb_ext
It store the information about the external ghost box.
size_t sub
sub-domain id of the non-extended sub-domain
Per-processor external ghost box.
::Box< dim, long int > l_e_box
Box defining the external ghost box in local coordinates for gdb_ext.
::Box< dim, long int > g_e_box
Box defining the external ghost box in global coordinates.
Per-processor external ghost box.
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:95
size_t r_sub
r_sub id of the sub-domain in the sent list
::Box< dim, long int > lr_e_box
Box defining the external box in local coordinates for received box.
size_t id
id of the box in the array that produced an non-empty intersection
Box< dim, long int > ibox
internal ghost box
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
size_t n_r_box
Number of received boxes.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
size_t prc
processor id
Result of the itersection of a box with an array of boxes.
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:708
Boundary conditions.
Definition: common.hpp:21
comb< dim > cmb
Sector position of the local external ghost box.
::Box< dim, long int > box
Box.