OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
CartesianGraphFactory.hpp
1 /*
2  * CartesianGraphFactory.hpp
3  *
4  * Created on: Nov 28, 2014
5  * Author: i-bird
6  */
7 
8 #ifndef CARTESIANGRAPHFACTORY_HPP_
9 #define CARTESIANGRAPHFACTORY_HPP_
10 
11 #include "Vector/map_vector.hpp"
12 #include "Graph/map_graph.hpp"
13 #include "Grid/grid_sm.hpp"
14 #include "Space/Shape/Box.hpp"
15 #include "Space/Shape/HyperCube.hpp"
16 
17 #define NO_VERTEX_ID -1
18 
25 template<unsigned int dim, typename G_v, int prp>
26 struct fill_id
27 {
29  static inline void fill(G_v & g_v, const grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs)
30  {
31  g_v.template get<prp>() = gs.LinId(gk);
32  }
33 };
39 template<unsigned int dim, typename G_v>
40 struct fill_id<dim, G_v, NO_VERTEX_ID>
41 {
43  static inline void fill(G_v & g_v, const grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs)
44  {
45  }
46 };
47 
76 template<unsigned int dim, int lin_id, typename dT, typename G_v, typename v, int impl>
77 class fill_prop
78 {
81 
83  const dT (&szd)[dim];
84 
87 
89  G_v & g_v;
90 
93 
94 public:
95 
97  fill_prop(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs, const Box<dim,dT> & domain)
98  :domain(domain), szd(szd), gk(gk), g_v(g_v), gs(gs)
99  {
100  }
101 
103  template<typename T>
104  void operator()(T& t) const
105  {
106  typedef typename boost::fusion::result_of::at<v, boost::mpl::int_<T::value>>::type t_val;
107 
108  g_v.template get<t_val::value>() = gk.get(T::value) * szd[T::value] + domain.getLow(T::value);
110  }
111 };
112 
139 template<unsigned int dim, int lin_id, typename dT, typename G_v, typename v>
140 class fill_prop<dim, lin_id, dT, G_v, v, 0>
141 {
142 
143 public:
144 
146  fill_prop(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs, const Box<dim,dT> & domain)
147  {
148  }
149 
151  template<typename T>
152  void operator()(T& t) const
153  {
154  }
155 };
156 
183 template<unsigned int dim, int lin_id, typename dT, typename G_v, typename v>
184 class fill_prop<dim, lin_id, dT, G_v, v, 2>
185 {
188 
190  const dT (&szd)[dim];
191 
194 
196  G_v & g_v;
197 
200 
201 public:
202 
204  fill_prop(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs, const Box<dim,dT> & domain)
205  :domain(domain), szd(szd), gk(gk), g_v(g_v), gs(gs)
206  {
207  }
208 
210  template<typename T>
211  void operator()(T& t) const
212  {
213  typedef typename boost::fusion::result_of::at<v, boost::mpl::int_<0>>::type t_val;
214  typedef typename boost::mpl::at<typename G_v::T_type::type,t_val>::type s_type;
215 
216  for (size_t i = 0 ; i < std::extent<s_type>::value ; i++)
217  g_v.template get<t_val::value>()[i] = 0.0;
218 
219  for (size_t i = 0 ; i < dim ; i++)
220  g_v.template get<t_val::value>()[i] = gk.get(i) * static_cast<float>(szd[i]) + domain.getLow(i);
221 
223  }
224 };
225 
233 template<int i, typename p, typename Graph, int ... pos>
235 {
236 
238  typedef typename boost::mpl::at<p, boost::mpl::int_<0>>::type v_element;
239 
241  typedef typename boost::mpl::at<typename Graph::V_type::type, v_element>::type pos_prop_type;
242 
243  enum
244  {
245  value = ((sizeof...(pos) != 0) * (std::is_array<pos_prop_type>::value + 1))
246  };
247 
248 };
249 
257 template<typename p, typename Graph, int ... pos>
258 struct fill_prop_by_type<0, p, Graph, pos...>
259 {
260  enum
261  {
262  value = 0
263  };
264 
265 };
266 
275 template<unsigned int dim, int lin_id, typename Graph, int se, typename T, unsigned int dim_c, int ... pos>
277 {
278 public:
279 
289  static Graph construct(const size_t (& sz)[dim], Box<dim,T> dom, const size_t(& bc)[dim])
290  {
291  // Calculate the size of the hyper-cubes on each dimension
292  T szd[dim];
293 
294  for (size_t i = 0; i < dim; i++)
295  {
296  szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];
297  }
298 
300 
301  HyperCube<dim> hc;
302 
303  // Construct a grid info
304 
305  grid_sm<dim, void> g(sz);
306 
307  // Create a graph with the number of vertices equal to the number of
308  // grid point
309 
311 
312  Graph gp(g.size());
313 
314  /******************
315  *
316  * Create the edges and fill spatial
317  * information properties
318  *
319  ******************/
320 
323 
325 
326  while (k_it.isNext())
327  {
328  grid_key_dx<dim> key = k_it.get();
329 
330  // Vertex object
331 
332  auto obj = gp.vertex(g.LinId(key));
333 
334  typedef typename to_boost_vmpl<pos...>::type p;
335 
336  // vertex spatial properties functor
337 
338  fill_prop<dim, lin_id, T, decltype(gp.vertex(g.LinId(key))), typename to_boost_vmpl<pos...>::type, fill_prop_by_type<sizeof...(pos), p, Graph, pos...>::value> flp(obj, szd, key, g, dom);
339 
340  // fill properties
341 
342  boost::mpl::for_each<boost::mpl::range_c<int, 0, sizeof...(pos)> >(flp);
343 
344  // Get the combinations of dimension d
345 
346  for (long int d = dim-1 ; d >= dim_c ; d--)
347  {
348  // create the edges for that dimension
349 
350  std::vector<comb<dim>> c = hc.getCombinations_R(d);
351 
352  // for each combination calculate a safe linearization and create an edge
353 
354  for (size_t j = 0; j < c.size(); j++)
355  {
356  // Calculate the element size
357 
358  T ele_sz = 0;
359 
360  // for each dimension multiply and reduce
361 
362 
363  for (size_t s = 0 ; s < dim ; s++)
364  ele_sz += szd[s] * abs(c[j][s]);
365 
366  // Calculate the end point vertex id
367  // Calculate the start point id
368 
369  size_t start_v = g.LinId(key);
370 
371  size_t end_v = g.template LinId<CheckExistence>(key,c[j].getComb(),bc);
372 
373  // Add an edge and set the the edge property to the size of the face (communication weight)
374  gp.template addEdge<CheckExistence>(start_v, end_v).template get<se>() = ele_sz;
375  }
376  }
377 
378  // Fill vertex properties
379 
380  ++k_it;
381  }
382 
383  return gp;
384  }
385 };
386 
396 template<unsigned int dim, int lin_id, typename Graph, typename T, unsigned int dim_c, int ... pos>
397 class Graph_constructor_impl<dim, lin_id, Graph, NO_EDGE, T, dim_c, pos...>
398 {
399 public:
400 
410  static Graph construct(const size_t ( & sz)[dim], Box<dim,T> dom, const size_t(& bc)[dim])
411  {
412  // Calculate the size of the hyper-cubes on each dimension
413 
414  T szd[dim];
415 
416  for (size_t i = 0; i < dim; i++)
417  {
418  szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];
419  }
420 
422 
423  HyperCube<dim> hc;
424 
425  // Construct a grid info
426 
427  grid_sm<dim, void> g(sz);
428 
429  // Create a graph with the number of vertices equal to the number of
430  // grid point
431 
433 
434  Graph gp(g.size());
435 
436  /******************
437  *
438  * Create the edges and fill spatial
439  * information properties
440  *
441  ******************/
442 
445 
447 
448  while (k_it.isNext())
449  {
450  grid_key_dx<dim> key = k_it.get();
451 
452  // Vertex object
453  auto obj = gp.vertex(g.LinId(key));
454 
455  typedef typename to_boost_vmpl<pos...>::type p;
456 
457  // vertex spatial properties functor
458 
459  fill_prop<dim, lin_id, T, decltype(gp.vertex(g.LinId(key))), typename to_boost_vmpl<pos...>::type, fill_prop_by_type<sizeof...(pos), p, Graph, pos...>::value> flp(obj, szd, key, g, dom);
460 
461  // fill properties
462 
463  boost::mpl::for_each_ref<boost::mpl::range_c<int, 0, sizeof...(pos)> >(flp);
464 
465  // Get the combinations of dimension d
466 
467  for (long int d = dim-1 ; d >= dim_c ; d--)
468  {
469  // create the edges for that dimension
470 
471  std::vector<comb<dim>> c = hc.getCombinations_R(d);
472 
473  // for each combination calculate a safe linearization and create an edge
474 
475  for (size_t j = 0; j < c.size(); j++)
476  {
477  // Calculate the end point vertex id
478  // Calculate the start point id
479 
480  size_t start_v = g.LinId(key);
481 
482  size_t end_v = g.template LinId<CheckExistence>(key,c[j].getComb(),bc);
483 
484  // Add an edge and set the the edge property to the size of the face (communication weight)
485  gp.template addEdge<CheckExistence>(start_v, end_v);
486  }
487  }
488 
489  // Fill vertex properties
490 
491  ++k_it;
492  }
493 
494  return gp;
495  }
496 };
497 
506 template<unsigned int dim, typename Graph>
508 {
509 
510 public:
511 
539  template<int se, int id_prp, typename T, unsigned int dim_c, int ... pos>
540  static Graph construct(const size_t (&sz)[dim], Box<dim, T> dom, const size_t (& bc)[dim])
541  {
543  }
544 };
545 
546 #endif /* CARTESIANGRAPHFACTORY_HPP_ */
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
const grid_sm< dim, void > & gs
grid info
This class work as a functor.
static std::vector< comb< dim > > getCombinations_R(size_t d)
Definition: HyperCube.hpp:100
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
Operator for vector and scalar property.
fill_prop(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs, const Box< dim, dT > &domain)
Fill the object from where to take the properties.
Graph constructor function specialization.
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom, const size_t(&bc)[dim])
Construct a cartesian graph.
G_v & g_v
Vertex object to fill.
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
fill_prop(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs, const Box< dim, dT > &domain)
Fill the object from where to take the properties.
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom, const size_t(&bc)[dim])
Construct a cartesian graph.
const Box< dim, dT > & domain
Domain.
This class construct a cartesian graph.
boost::mpl::at< typename Graph::V_type::type, v_element >::type pos_prop_type
Get the property v_element (v_element is a number)
static void fill(G_v &g_v, const grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs)
function that fill with linearization indexes
static void fill(G_v &g_v, const grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs)
function that fill with linearization indexes
const dT(& szd)[dim]
Reference to an array containing the spacing.
void operator()(T &t) const
It call the function for each property we want to copy.
fill_prop(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs, const Box< dim, dT > &domain)
Fill the object from where to take the properties.
boost::mpl::at< p, boost::mpl::int_< 0 > >::type v_element
Get the element 0.
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
void operator()(T &t) const
It call the function for each property we want to copy.
void operator()(T &t) const
It call the function for each property we want to copy.
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
This class calculate elements of the hyper-cube.
Definition: HyperCube.hpp:57
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom, const size_t(&bc)[dim])
Construct a cartesian graph, with V and E edge properties.
Operator to fill the property 'prp' with the linearization of indexes.
const grid_sm< dim, void > & gs
grid info