OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
CartDecomposition_ext.hpp
1 /*
2  * CartDecomposition_ext.hpp
3  *
4  * Created on: Mar 6, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
9 #define SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
10 
11 #include "memory/HeapMemory.hpp"
12 #include "Decomposition/Distribution/ParMetisDistribution.hpp"
13 #include "Space/Ghost.hpp"
14 #include "Decomposition/nn_processor.hpp"
15 
16 template<unsigned int dim, typename T, typename Memory = HeapMemory, typename Distribution = ParMetisDistribution<dim, T>>
17 class CartDecomposition;
18 
41 template<unsigned int dim, typename T, typename Memory = HeapMemory, typename Distribution = ParMetisDistribution<dim, T>>
42 class CartDecomposition_ext: public CartDecomposition<dim,T,Memory,Distribution>
43 {
44 private:
45 
54  void extend_subdomains(const CartDecomposition<dim,T,Memory,Distribution> & dec, const ::Box<dim,T> & ext_dom)
55  {
56  // Box
57  typedef ::Box<dim,T> b;
58 
59  this->bbox.zero();
60 
61  // Extend sub-domains
62  for (size_t i = 0 ; i < dec.sub_domains.size() ; i++)
63  {
64  ::Box<dim,T> box;
65 
66  // Calculate the extended box
67  for (size_t j = 0 ; j < dim ; j++)
68  {
69  if (dec.sub_domains.template get<b::p1>(i)[j] == dec.domain.getLow(j))
70  box.setLow(j,ext_dom.getLow(j));
71  else
72  box.setLow(j,dec.sub_domains.template get<b::p1>(i)[j]);
73 
74  if (dec.sub_domains.template get<b::p2>(i)[j] == dec.domain.getHigh(j))
75  box.setHigh(j,ext_dom.getHigh(j));
76  else
77  box.setHigh(j,dec.sub_domains.template get<b::p2>(i)[j]);
78  }
79 
80  // add the subdomain
81  this->sub_domains.add(box);
82 
83  // Calculate the bound box
84  this->bbox.enclose(box);
85  }
86  }
87 
94  {
95  // Extension, first we calculate the extensions of the new domain compared
96  // to the old one in cell units (each cell unit is a sub-sub-domain)
98  // Extension of the new fines structure
99  ::Box<dim,size_t> n_fines_ext;
100  // Extension of the old fines structure
101  ::Box<dim,size_t> o_fines_ext;
102 
103  size_t sz_new[dim];
104  size_t sz_old[dim];
105 
106  for (size_t i = 0; i < dim ; i++)
107  {
108  size_t p1 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
109  size_t p2 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
110 
111  ext.setLow(i,p1);
112  ext.setHigh(i,p2);
113  sz_new[i] = p1+p2+dec.cd.getGrid().size(i);
114  sz_old[i] = dec.cd.getGrid().size(i);
115  }
116 
117  grid_sm<dim,void> info_new(sz_new);
118  grid_sm<dim,void> info_old(sz_old);
119 
120  // resize the new fines
121  this->fine_s.resize(info_new.size());
122 
123  // we create an iterator that iterate across the full new fines
124  grid_key_dx_iterator<dim> fines_t(info_new);
125 
126  while (fines_t.isNext())
127  {
128  auto key = fines_t.get();
129 
130  // new_fines is bigger than old_fines structure
131  // out of bound key must be adjusted
132  // The adjustment produce a natural extension
133  // a representation can be seen in the figure of
134  // CartDecomposition duplicate function with extended domains
135 
136  grid_key_dx<dim> key_old;
137  for (size_t i = 0 ; i < dim ; i++)
138  {
139  key_old.set_d(i,(long int)key.get(i) - ext.getLow(i));
140  if (key_old.get(i) < 0)
141  key_old.set_d(i,0);
142  else if(key_old.get(i) >= (long int)info_old.size(i) )
143  key_old.set_d(i,info_old.size(i)-1);
144  }
145 
146  this->fine_s.get(info_new.LinId(key)) = dec.fine_s.get(info_old.LinId(key_old));
147 
148  ++fines_t;
149  }
150 
151  this->gr.setDimensions(sz_new);
152 
153  // the new extended CellDecomposer must be consistent with the old cellDecomposer.
154  this->cd.setDimensions(dec.cd,ext);
155  }
156 
157 public:
158 
165  :CartDecomposition<dim,T,Memory,Distribution>(v_cl)
166  {
167  }
168 
171 
213  void setParameters(const CartDecomposition<dim,T,Memory,Distribution> & dec, const Ghost<dim,T> & g, const ::Box<dim,T> & ext_domain)
214  {
216 
217  // Calculate new sub-domains for extended domain
218  extend_subdomains(dec,ext_domain);
219 
220  // Calculate fine_s structure for the extended domain
221  // update the cell decomposer and gr
222  extend_fines(dec);
223 
224  // Get the old sub-sub-domain grid extension
225 
226  this->domain = ext_domain;
227 
228  // spacing does not change
229 
230  for (size_t i = 0 ; i < dim ; i++)
231  {this->spacing[i] = dec.spacing[i];};
232 
233  this->ghost = g;
234  this->dist = dec.dist;
235 
236  for (size_t i = 0 ; i < dim ; i++)
237  this->bc[i] = dec.bc[i];
238 
239  (static_cast<nn_prcs<dim,T> &>(*this)).create(this->box_nn_processor, this->sub_domains);
240  (static_cast<nn_prcs<dim,T> &>(*this)).applyBC(ext_domain,g,this->bc);
241 
243  this->calculateGhostBoxes();
244  }
245 
246 };
247 
248 
249 
250 #endif /* SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_ */
openfpm::vector< size_t > fine_s
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
CellDecomposer_sm< dim, T, shift< dim, T > > cd
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:337
void extend_subdomains(const CartDecomposition< dim, T, Memory, Distribution > &dec, const ::Box< dim, T > &ext_dom)
It copy the sub-domains into another CartesianDecomposition object extending them.
Vcluster & v_cl
Runtime virtual cluster machine.
This class decompose a space into sub-sub-domains and distribute them across processors.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
CartDecomposition_ext(Vcluster &v_cl)
Cartesian decomposition constructor.
::Box< dim, T > bbox
Processor bounding box.
CartDecomposition< dim, T, Memory, Distribution > base_type
The non-extended decomposition base class.
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
T spacing[dim]
Box Spacing.
void extend_fines(const CartDecomposition< dim, T, Memory, Distribution > &dec)
Extend the fines for the new Cartesian decomposition.
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
size_t size()
Stub size.
Definition: map_vector.hpp:70
Definition: Ghost.hpp:39
Distribution dist
Create distribution.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
Implementation of VCluster class.
Definition: VCluster.hpp:36
void setParameters(const CartDecomposition< dim, T, Memory, Distribution > &dec, const Ghost< dim, T > &g, const ::Box< dim, T > &ext_domain)
It create another object that contain the same decomposition information but with different ghost box...
This class decompose a space into sub-sub-domains and distribute them across processors.
void Initialize_geo_cell_lists()
Initialize geo_cell lists.
const grid_key_dx< dim > & get() const
Get the actual key.
Ghost< dim, T > ghost
ghost info
size_t bc[dim]
Boundary condition info.
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
bool isNext()
Check if there is the next element.
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
void calculateGhostBoxes()
It calculate the internal ghost boxes.
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
::Box< dim, T > domain
rectangular domain to decompose
openfpm::vector< SpaceBox< dim, T > > sub_domains
the set of all local sub-domain as vector
openfpm::vector< openfpm::vector< long unsigned int > > box_nn_processor
for each sub-domain, contain the list of the neighborhood processors
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:229
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.