From 78da786a739498e134b7c20f4603db228ed9ed5c Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Tue, 10 Mar 2015 19:31:30 +0100
Subject: [PATCH] Added vector iterator

---
 src/Decomposition/CartDecomposition.hpp |   6 +-
 src/Grid/grid_dist_id.hpp               | 189 ++++++++++++++++++++++++
 src/Grid/grid_dist_id_iterator.hpp      |  15 ++
 src/Grid/grid_dist_id_unit_test.hpp     |  16 ++
 src/Grid/grid_dist_key.hpp              |  20 +++
 src/Space/space.hpp                     | 145 ++++++++++++++++++
 src/Space/space_key.hpp                 | 179 ++++++++++++++++++++++
 src/Vector/vector_dist.hpp              | 133 +++++++++++++++++
 src/Vector/vector_dist_iterator.hpp     | 113 ++++++++++++++
 src/Vector/vector_dist_key.hpp          |  60 ++++++++
 src/Vector/vector_dist_unit_test.hpp    |  31 ++++
 src/main.cpp                            |   1 +
 src/metis_util_unit_test.hpp            |   2 +-
 13 files changed, 906 insertions(+), 4 deletions(-)
 create mode 100644 src/Space/space.hpp
 create mode 100644 src/Space/space_key.hpp
 create mode 100644 src/Vector/vector_dist.hpp
 create mode 100644 src/Vector/vector_dist_iterator.hpp
 create mode 100644 src/Vector/vector_dist_key.hpp
 create mode 100644 src/Vector/vector_dist_unit_test.hpp

diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp
index c2636bfd..9d0ffaee 100644
--- a/src/Decomposition/CartDecomposition.hpp
+++ b/src/Decomposition/CartDecomposition.hpp
@@ -38,7 +38,7 @@
  *
  */
 
-template<unsigned int dim, typename T, template<typename> class device_l=openfpm::device_cpu, typename Memory=HeapMemory, template<unsigned int, typename> class Domain=Box, template<typename, typename, typename, typename> class data_s = openfpm::vector>
+template<unsigned int dim, typename T, template<typename> class device_l=openfpm::device_cpu, typename Memory=HeapMemory, template<unsigned int, typename> class Domain=Box, template<typename, typename, typename, typename, unsigned int> class data_s = openfpm::vector>
 class CartDecomposition
 {
 public:
@@ -52,7 +52,7 @@ private:
 
 	//! This is the access_key to data_s, for example in the case of vector
 	//! acc_key is size_t
-	typedef typename data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default>::access_key acc_key;
+	typedef typename data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default,openfpm::vect_isel<SpaceBox<dim,T>>::value >::access_key acc_key;
 
 	//! Subspace selected
 	//! access_key in case of grid is just the set of the index to access the grid
@@ -62,7 +62,7 @@ private:
 	SpaceBox<dim,T> sub_domain;
 
 	//! the set of all local sub-domain as vector
-	data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default> sub_domains;
+	data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default, openfpm::vect_isel<SpaceBox<dim,T>>::value > sub_domains;
 
 	//! number of total sub-domain
 	size_t N_tot;
diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index d23dc5c6..eb33fffe 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -234,6 +234,195 @@ public:
 	{
 		return v_cl;
 	}
+
+	/*! \brief Get the reference of the selected element
+	 *
+	 *
+	 * \param p property to get (is an integer)
+	 * \param v1 grid_key that identify the element in the grid
+	 *
+	 */
+	template <unsigned int p>inline auto get(grid_dist_key_dx<dim> & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
+	{
+		return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
+	}
+};
+
+/*! \brief This is a distributed grid
+ *
+ * Implementation of a distributed grid with id decomposition. A distributed grid is a grid distributed
+ * across processors. The decomposition is performed on the id of the elements
+ *
+ * [Examples]
+ *
+ * on 1D where the id is from 1 to N
+ * processor k take M contiguous elements
+ *
+ * on 3D where (for example)
+ * processor k take M id-connected elements
+ *
+ * \param dim Dimensionality of the grid
+ * \param T type of grid
+ * \param Decomposition Class that decompose the grid for example CartDecomposition
+ * \param Mem Is the allocator
+ * \param device type of base structure is going to store the data
+ *
+ */
+
+template<typename T, typename Decomposition,typename Memory , typename device_grid >
+class grid_dist_id<1,T,Decomposition,Memory,device_grid>
+{
+	// Ghost expansion
+	Box<1,size_t> ghost;
+
+	//! Local grids
+	Vcluster_object_array<device_grid> loc_grid;
+
+	//! Size of the grid on each dimension
+	size_t g_sz[1];
+
+	//! Communicator class
+
+	Vcluster & v_cl;
+
+	/*! \brief Get the grid size
+	 *
+	 * Get the grid size, given a domain, the resolution on it and another spaceBox
+	 * it give the size on all directions of the local grid
+	 *
+	 * \param sp SpaceBox enclosing the local grid
+	 * \param domain Space box enclosing the physical domain or part of it
+	 * \param v_size grid size on this physical domain
+	 *
+	 * \return An std::vector representing the local grid on each dimension
+	 *
+	 */
+	std::vector<size_t> getGridSize(SpaceBox<1,typename Decomposition::domain_type> & sp, Box<1,typename Decomposition::domain_type> & domain, size_t (& v_size)[1])
+	{
+		std::vector<size_t> tmp;
+		for (size_t d = 0 ; d < 1 ; d++)
+		{
+			// push the size of the local grid
+			tmp.push_back(g_sz[0]);
+		}
+		return tmp;
+	}
+
+	/*! \brief Get the grid size
+	 *
+	 * Get the grid size, given a spaceBox
+	 * it give the size on all directions of the local grid
+	 *
+	 * \param sp SpaceBox enclosing the local grid
+	 * \param sz array to fill with the local grid size on each dimension
+	 *
+	 */
+	void getGridSize(SpaceBox<1,size_t> & sp, size_t (& v_size)[1])
+	{
+		for (size_t d = 0 ; d < 1 ; d++)
+		{
+			// push the size of the local grid
+			v_size[d] = sp.getHigh(d) - sp.getLow(d) + 1;
+		}
+	}
+
+public:
+
+	//! constructor
+	grid_dist_id(Vcluster v_cl, Decomposition & dec, size_t (& g_sz)[1], Box<1,size_t> & ghost)
+	:ghost(ghost),loc_grid(NULL),v_cl(v_cl)
+	{
+		// fill the global size of the grid
+		for (int i = 0 ; i < 1 ; i++)	{this->g_sz[i] = g_sz[i];}
+
+		// Create local memory
+		Create();
+	}
+
+	//! constructor
+	grid_dist_id(size_t (& g_sz)[1])
+	:v_cl(*global_v_cluster)
+	{
+		// fill the global size of the grid
+		for (int i = 0 ; i < 1 ; i++)	{this->g_sz[i] = g_sz[i];}
+
+		// Create local memory
+		Create();
+	}
+
+	/*! \brief Create the grid on memory
+	 *
+	 */
+
+	void Create()
+	{
+		size_t n_grid = 1;
+
+		// create local grids for each hyper-cube
+
+		loc_grid = v_cl.allocate<device_grid>(n_grid);
+
+		// Size of the grid on each dimension
+		size_t l_res[1];
+
+		// Calculate the local grid size
+
+		l_res[0] = g_sz[0] / v_cl.getProcessingUnits();
+
+		// Distribute the remaining
+
+		size_t residual = g_sz[0] % v_cl.getProcessingUnits();
+		if (v_cl.getProcessUnitID() < residual)
+			l_res[0]++;
+
+		// Set the dimensions of the local grid
+
+		loc_grid.get(0).template resize<Memory>(l_res);
+	}
+
+	/*! \brief It return an iterator of the bulk part of the grid with a specified margin
+	 *
+	 * For margin we mean that every point is at least m points far from the border
+	 *
+	 * \param m margin
+	 *
+	 * \return An iterator to a grid with specified margins
+	 *
+	 */
+	grid_dist_iterator<1,device_grid> getDomainIterator()
+	{
+		grid_dist_iterator<1,device_grid> it(loc_grid,0);
+
+		return it;
+	}
+
+	//! Destructor
+	~grid_dist_id()
+	{
+	}
+
+	/*! \brief Get the Virtual Cluster machine
+	 *
+	 * \return the Virtual cluster machine
+	 *
+	 */
+
+	Vcluster & getVC()
+	{
+		return v_cl;
+	}
+
+	/*! \brief Get the reference of the selected element
+	 *
+	 *
+	 * \param p property to get (is an integer)
+	 * \param v1 grid_key that identify the element in the grid
+	 *
+	 */
+	template <unsigned int p>inline auto get(grid_dist_key_dx<1> & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
+	{
+		return loc_grid.get(0).template get<p>(v1.getKey());
+	}
 };
 
 #endif
diff --git a/src/Grid/grid_dist_id_iterator.hpp b/src/Grid/grid_dist_id_iterator.hpp
index 510a69de..72097d53 100644
--- a/src/Grid/grid_dist_id_iterator.hpp
+++ b/src/Grid/grid_dist_id_iterator.hpp
@@ -53,6 +53,21 @@ class grid_dist_iterator
 	{
 	}
 
+	/*! \brief operator=
+	 *
+	 * assign
+	 *
+	 */
+	grid_dist_iterator<dim,device_grid> & operator=(const grid_dist_iterator<dim,device_grid> & gdi)
+	{
+		g_c = gdi.g_c;
+		gList = gdi.gList;
+		a_it = gdi.a_it;
+		m = gdi.m;
+
+		return *this;
+	}
+
 	/*! \brief Get the next element
 	 *
 	 * \return the next grid_key
diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp
index 4f373a74..2bb9530e 100644
--- a/src/Grid/grid_dist_id_unit_test.hpp
+++ b/src/Grid/grid_dist_id_unit_test.hpp
@@ -50,11 +50,27 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
 	{
 		auto key = dom.get();
 
+		g_dist.template get<0>(key) = count;
+
+		// Count the point
 		count++;
 
 		++dom;
 	}
 
+	size_t count_check = 0;
+	dom = g_dist.getDomainIterator();
+
+	while (dom.isNext())
+	{
+		auto key = dom.get();
+
+		BOOST_REQUIRE_EQUAL(g_dist.template get<0>(key),count_check);
+
+		count_check++;
+		++dom;
+	}
+
 	// Get the virtual cluster machine
 	Vcluster & vcl = g_dist.getVC();
 
diff --git a/src/Grid/grid_dist_key.hpp b/src/Grid/grid_dist_key.hpp
index ae8c7cd2..ab8ef5b2 100644
--- a/src/Grid/grid_dist_key.hpp
+++ b/src/Grid/grid_dist_key.hpp
@@ -20,6 +20,26 @@ class grid_dist_key_dx
 
 public:
 
+	/*! \brief Get the local grid
+	 *
+	 * \return the id of the local grid
+	 *
+	 */
+	size_t getSub()
+	{
+		return g_c;
+	}
+
+	/*! \brief Get the key
+	 *
+	 * \return the local key
+	 *
+	 */
+	grid_key_dx<dim> getKey()
+	{
+		return key;
+	}
+
 	grid_dist_key_dx(int g_c, grid_key_dx<dim> key)
 	:g_c(g_c),key(key)
 	{
diff --git a/src/Space/space.hpp b/src/Space/space.hpp
new file mode 100644
index 00000000..87fa2662
--- /dev/null
+++ b/src/Space/space.hpp
@@ -0,0 +1,145 @@
+/*
+ * spaces.hpp
+ *
+ *  Created on: Mar 10, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef SPACES_HPP_
+#define SPACES_HPP_
+
+template<unsigned int dim, typename T> class space
+{
+public:
+
+  typedef boost::fusion::vector<> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int max_prop = 0;
+};
+
+
+template<typename T> class space<1,T>
+{
+public:
+
+  typedef boost::fusion::vector<T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int x = 0;
+
+  static const unsigned int max_prop = 1;
+};
+
+template<typename T> class space<2,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int x = 0;
+  static const unsigned int y = 1;
+
+  static const unsigned int max_prop = 2;
+};
+
+template<typename T> class space<3,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int x = 0;
+  static const unsigned int y = 1;
+  static const unsigned int z = 2;
+
+  static const unsigned int max_prop = 3;
+};
+
+template<typename T> class space<4,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int x = 0;
+  static const unsigned int y = 1;
+  static const unsigned int z = 2;
+  static const unsigned int t = 3;
+
+  static const unsigned int max_prop = 4;
+};
+
+template<typename T> class space<5,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int max_prop = 5;
+};
+
+
+template<typename T> class space<6,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T,T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int max_prop = 6;
+};
+
+
+template<typename T> class space<7,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T,T,T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int max_prop = 7;
+};
+
+template<typename T> class space<8,T>
+{
+public:
+
+  typedef boost::fusion::vector<T,T,T,T,T,T,T,T> type;
+  typedef typename memory_traits_inte<type>::type memory_int;
+  typedef typename memory_traits_lin<type>::type memory_lin;
+
+  type data;
+
+  static const unsigned int max_prop = 8;
+};
+
+#endif /* SPACES_HPP_ */
diff --git a/src/Space/space_key.hpp b/src/Space/space_key.hpp
new file mode 100644
index 00000000..c5553362
--- /dev/null
+++ b/src/Space/space_key.hpp
@@ -0,0 +1,179 @@
+/*
+ * space_key.hpp
+ *
+ *  Created on: Mar 6, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef SPACE_KEY_HPP_
+#define SPACE_KEY_HPP_
+
+
+/*! \brief grid_key_dx is the key to access any element in the grid
+ *
+ * grid_key_dx is the key to access any element in the grid
+ *
+ * \tparam dim dimensionality of the grid
+ * \tparam T type of the space float, double, complex, ...
+ *
+ */
+
+template<unsigned int dim, typename T>
+class space_key_dx
+{
+public:
+
+	//! Constructor
+	space_key_dx()
+	{}
+
+	//! Constructor from buffer
+	space_key_dx(T (& k)[dim])
+	{
+		for (int i = 0 ; i < dim ; i++)
+			this->k[i] = k[i];
+	}
+
+	//! Constructor from buffer
+	space_key_dx(const T (& k)[dim])
+	{
+		for (int i = 0 ; i < dim ; i++)
+			this->k[i] = k[i];
+	}
+
+	//! Construct a grid key from a list of numbers
+	space_key_dx(const T v,const T...t)
+	{
+		k[dim-1] = v;
+		invert_assign(t...);
+	}
+
+	/*! \brief Set to zero the key
+	 */
+	inline void zero()
+	{
+		for (int i = 0 ; i < dim ; i++)
+		{
+			k[i] = 0;
+		}
+	}
+
+	/*! \brief Set to invalid the key
+	 */
+	inline void invalid()
+	{
+		for (int i = 0 ; i < dim ; i++)
+		{
+			k[i] = -1;
+		}
+	}
+
+	/* \brief Check if two key are the same
+	 *
+	 * \param key_t key to check
+	 *
+	 * \return true if the two key are identical
+	 *
+	 */
+
+	template<unsigned int dim_t> bool operator==(space_key_dx<dim_t,T> & key_t)
+	{
+		if (dim != dim_t)
+		{
+			return false;
+		}
+
+		// Check the two key index by index
+
+		for (int i = 0 ; i < dim ; i++)
+		{
+			if (k[i] != key_t.k[i])
+			{
+				return false;
+			}
+		}
+
+		// identical key
+		return true;
+	}
+
+	//! set the grid key from a list of numbers
+	template<typename a, typename ...T>void set(a v, T...t)
+	{
+		k[dim-1] = v;
+		invert_assign(t...);
+	}
+
+	/*! \brief Get the i index
+	 *
+	 * \param i index to get
+	 *
+	 * \return the index value
+	 *
+	 */
+	mem_id value(size_t i) const
+	{
+		return k[i];
+	}
+
+	/*! \brief Get the i index
+	 *
+	 *
+	 * \param i index to get
+	 *
+	 * \return the index value
+	 *
+	 */
+	mem_id get(size_t i) const
+	{
+		return k[i];
+	}
+
+	/*! \brief Set the i index
+	 *
+	 * Set the i index
+	 *
+	 * \param i index to set
+	 * \param id value to set
+	 *
+	 */
+	void set_d(size_t i, mem_id id)
+	{
+#ifdef DEBUG
+
+		if (i >= dim)
+			std::cerr << "grid_key_dx error: " << __FILE__ << " " << __LINE__ << " try to access dimension " << i << " on a grid_key_dx of size " << dim << "\n";
+
+#endif
+		k[i] = id;
+	}
+
+	//! structure that store all the index
+	mem_id k[dim];
+
+private:
+
+	/*! \brief Recursively invert the assignment
+	 *
+	 * Recursively invert the assignment at compile-time
+	 *
+	 */
+	template<typename a, typename ...T>void invert_assign(a v,T...t)
+	{
+		k[sizeof...(T)] = v;
+		invert_assign(t...);
+	}
+
+	template<typename a, typename ...T>void invert_assign(a v)
+	{
+		k[0] = v;
+	}
+
+	void invert_assign()
+	{
+	}
+
+};
+
+
+#endif /* SPACE_KEY_HPP_ */
diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp
new file mode 100644
index 00000000..f84e9cd8
--- /dev/null
+++ b/src/Vector/vector_dist.hpp
@@ -0,0 +1,133 @@
+/*
+ * Vector.hpp
+ *
+ *  Created on: Mar 5, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef VECTOR_HPP_
+#define VECTOR_HPP_
+
+#include "Space/space.hpp"
+
+#define NO_ID false
+#define ID true
+
+/*! \brief Distributed vector
+ *
+ *
+ *
+ */
+
+template<typename space, typename prop, typename Box, typename Decomposition , typename Memory=HeapMemory, bool with_id=false>
+class vector_dist
+{
+private:
+
+	//! Space Decomposition
+	Decomposition dec;
+
+	// Space for space position
+	grid_dist_id<1,space,Decomposition,Memory> pos;
+
+	// Space for properties
+	grid_dist_id<1,prop,Decomposition,Memory> prp;
+
+	// Virtual cluster
+	Vcluster & v_cl;
+
+public:
+
+	/*! \brief Constructor
+	 *
+	 * \param number of elements
+	 *
+	 */
+	vector_dist(size_t np)
+	:dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster)
+	{
+		// resize the position vector
+		pos.resize(np);
+
+		// resize the properties vector
+		prp.resize(np);
+
+		// Create a valid decomposition of the space
+		// Get the number of processor and calculate the number of sub-domain
+		// for decomposition
+		size_t n_proc = v_cl.getProcessingUnits();
+		size_t n_sub = n_proc * SUB_UNIT_FACTOR;
+
+		// Calculate the maximum number (before merging) of sub-domain on
+		// each dimension
+		size_t div[space::size];
+		for (int i = 0 ; i < space::size ; i++)
+		{div[i] = round_big_2(pow(n_sub,1.0/space::size));}
+
+		// Create the sub-domains
+		dec.setParameters(div);
+	}
+
+	/*! \brief Get position of an object
+	 *
+	 * \param vec_key vector element
+	 *
+	 */
+	template<unsigned int id> auto getPos(size_t vec_key) -> decltype(pos.template get<id>(vec_key))
+	{
+		return pos.template get<id>(vec_key);
+	}
+
+	/*! \brief Get the property of the object
+	 *
+	 * \param vec_key vector element
+	 *
+	 */
+	template<unsigned int id> auto getProp(size_t vec_key) -> decltype(prp.template get<id>(vec_key))
+	{
+		return prp.template get<id>(vec_key);
+	}
+
+	/*! \brief It communicate the particle to the respective processor
+	 *
+	 */
+	void map()
+	{
+		// allocate n vector with n = number of processors
+//		boost::shared_ptr<openfpm::vector<space>> (new openfpm::vector<space>[v_cl.getProcessingUnits()]);
+
+		// allocate n vector with n = number of processors
+//		boost::shared_ptr<openfpm::vector<prop>> (new openfpm::vector<space>[v_cl.getProcessingUnits()]);
+
+		// Contain the map of the processor should communicate
+		openfpm::vector<unsigned char> p_map;
+
+		// Contain the processor id of each particle (basically where they have to go)
+		openfpm::vector<size_t> lbl_p(pos.size());
+
+		// It contain the list of the processors it should to communicate
+		openfpm::vector<size_t> p_list;
+
+		auto it = pos.getIterator();
+
+		// Label all the particles it the processor id where they should go
+		while (it.isNext())
+		{
+			auto key = it.get();
+
+			size_t p_id = dec.processorID(pos.get_o(key));
+
+			lbl_p.get(key) = p_id;
+
+			// It has to communicate
+			p_map.get(p_id) = 1;
+
+			++it;
+		}
+	}
+
+
+};
+
+
+#endif /* VECTOR_HPP_ */
diff --git a/src/Vector/vector_dist_iterator.hpp b/src/Vector/vector_dist_iterator.hpp
new file mode 100644
index 00000000..9ac4f920
--- /dev/null
+++ b/src/Vector/vector_dist_iterator.hpp
@@ -0,0 +1,113 @@
+/*
+ * vector_dist_iterator.hpp
+ *
+ *  Created on: Mar 10, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef VECTOR_DIST_ITERATOR_HPP_
+#define VECTOR_DIST_ITERATOR_HPP_
+
+#include "VCluster.hpp"
+
+template<unsigned int dim, typename device_v>
+class vector_dist_iterator
+{
+	//! vector list counter
+	size_t v_c;
+
+	//! List of the grids we are going to iterate
+	Vcluster_object_array<device_v> & vList;
+
+	//! Actual iterator
+	size_t v_it;
+
+	public:
+
+	/*! \brief Constructor of the distributed grid
+	 *
+	 * \param gk std::vector of the local grid
+	 *
+	 */
+	vector_dist_iterator(Vcluster_object_array<device_v> & gk)
+	:v_c(0),vList(gk),v_it(0)
+	{
+	}
+
+	// Destructor
+	~vector_dist_iterator()
+	{
+	}
+
+	/*! \brief operator=
+	 *
+	 * assign
+	 *
+	 */
+	vector_dist_iterator<dim,device_v> & operator=(const vector_dist_iterator<dim,device_v> & vdi)
+	{
+		v_c = vdi.v_c;
+		vList = vdi.vList;
+		v_it = vdi.v_it;
+
+		return *this;
+	}
+
+	/*! \brief Get the next element
+	 *
+	 * \return the next grid_key
+	 *
+	 */
+
+	vector_dist_iterator<dim,device_v> operator++()
+	{
+		++v_it;
+
+		// check if a_it is at the end
+
+		if (v_it.isNext() == true)
+			return *this;
+		else
+		{
+			// switch to the new grid
+
+			v_c++;
+
+			// get the next grid iterator
+
+			if (v_c < vList.size())
+				v_it = vList[v_c].getDomainIterator();
+		}
+
+		return *this;
+	}
+
+	/*! \brief Check if there is the next element
+	 *
+	 * \return true if there is the next, false otherwise
+	 *
+	 */
+
+	bool isNext()
+	{
+		// If there are no other grid stop
+
+		if (v_c >= vList.size())
+			return false;
+
+		return true;
+	}
+
+	/*! \brief Get the actual key
+	 *
+	 * \return the actual key
+	 *
+	 */
+	size_t get()
+	{
+		return vect_dist_key_dx<dim>(v_c,v_it.get());
+	}
+};
+
+
+#endif /* VECTOR_DIST_ITERATOR_HPP_ */
diff --git a/src/Vector/vector_dist_key.hpp b/src/Vector/vector_dist_key.hpp
new file mode 100644
index 00000000..e367f7c4
--- /dev/null
+++ b/src/Vector/vector_dist_key.hpp
@@ -0,0 +1,60 @@
+/*
+ * vector_dist_key.hpp
+ *
+ *  Created on: Mar 10, 2015
+ *      Author: i-bird
+ */
+
+#ifndef VECTOR_DIST_KEY_HPP_
+#define VECTOR_DIST_KEY_HPP_
+
+
+
+/*! \brief Grid key for a distributed grid
+ *
+ * Grid key for a distributed grid
+ *
+ */
+
+template<unsigned int dim>
+class vect_dist_key_dx
+{
+	//! grid list counter
+
+	size_t v_c;
+
+	//! Local grid iterator
+
+	size_t key;
+
+public:
+
+	/*! \brief Get the local grid
+	 *
+	 * \return the id of the local grid
+	 *
+	 */
+	size_t getSub()
+	{
+		return v_c;
+	}
+
+	/*! \brief Get the key
+	 *
+	 * \return the local key
+	 *
+	 */
+	size_t getKey()
+	{
+		return key;
+	}
+
+	vect_dist_key_dx(int v_c, size_t key)
+	:v_c(v_c),key(key)
+	{
+	}
+};
+
+
+
+#endif /* VECTOR_DIST_KEY_HPP_ */
diff --git a/src/Vector/vector_dist_unit_test.hpp b/src/Vector/vector_dist_unit_test.hpp
new file mode 100644
index 00000000..896e6d31
--- /dev/null
+++ b/src/Vector/vector_dist_unit_test.hpp
@@ -0,0 +1,31 @@
+/*
+ * vector_dist_unit_test.hpp
+ *
+ *  Created on: Mar 6, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef VECTOR_DIST_UNIT_TEST_HPP_
+#define VECTOR_DIST_UNIT_TEST_HPP_
+
+#include "Vector/vector_dist.hpp"
+
+BOOST_AUTO_TEST_SUITE( vector_dist_test )
+
+BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use)
+{
+	vector_dist<space<2,float>, Point_test<float>, Box<2,float>, CartDecomposition<2,float> > vd(4096);
+
+	auto it = vd.getIterator();
+
+	while (it.isNext())
+	{
+
+
+		++it;
+	}
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+#endif /* VECTOR_DIST_UNIT_TEST_HPP_ */
diff --git a/src/main.cpp b/src/main.cpp
index 1de016b8..c7cb377a 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,5 +19,6 @@
 #include "metis_util_unit_test.hpp"
 #include "dec_optimizer_unit_test.hpp"
 #include "Grid/grid_dist_id_unit_test.hpp"
+#include "Vector/vector_dist_unit_test.hpp"
 #include "Decomposition/CartDecomposition_unit_test.hpp"
 
diff --git a/src/metis_util_unit_test.hpp b/src/metis_util_unit_test.hpp
index c09dd566..7638a206 100644
--- a/src/metis_util_unit_test.hpp
+++ b/src/metis_util_unit_test.hpp
@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE( Metis_test_use)
 
 	// Convert the graph to metis
 
-	Metis<Graph_CSR<nm_v,nm_e>> met(g,16);
+	Metis<Graph_CSR<nm_v,nm_e>> met(g,8);
 
 	// decompose
 
-- 
GitLab