diff --git a/openfpm_numerics b/openfpm_numerics
index 1a6ed29114ae41e2befcfcfb33ffab58986b6f6b..b4d8373acf148fcfb868fc3edff3eb2aed78c881 160000
--- a/openfpm_numerics
+++ b/openfpm_numerics
@@ -1 +1 @@
-Subproject commit 1a6ed29114ae41e2befcfcfb33ffab58986b6f6b
+Subproject commit b4d8373acf148fcfb868fc3edff3eb2aed78c881
diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index f75525113780f51f0b3bcdfadaa5b095486c775b..67b80376e4b8333576cd3d69887ad94f9dfd21f9 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -80,6 +80,12 @@ class grid_dist_id
 	// Receiving buffer for particles ghost get
 	openfpm::vector<HeapMemory> recv_mem_gg;
 
+	// Grid informations object
+	grid_sm<dim,T> ginfo;
+
+	// Grid informations object without type
+	grid_sm<dim,void> ginfo_v;
+
 	/*! \brief Call-back to allocate buffer to receive incoming objects (external ghost boxes)
 	 *
 	 * \param msg_i message size required to receive from i
@@ -350,11 +356,63 @@ class grid_dist_id
 		}
 	}
 
+	/*! \brief Create the grids on memory
+	 *
+	 */
+	void Create()
+	{
+		Box<dim,St> g_rnd_box;
+		for (size_t i = 0 ; i < dim ; i++)	{g_rnd_box.setHigh(i,0.5); g_rnd_box.setLow(i,-0.5);}
+
+		// Get the number of local grid needed
+		size_t n_grid = dec.getNLocalHyperCube();
+
+		// 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[dim];
+
+		// Allocate the grids
+		for (size_t i = 0 ; i < n_grid ; i++)
+		{
+			gdb_ext.add();
+
+			// Get the local hyper-cube
+			SpaceBox<dim,St> sp = dec.getLocalHyperCube(i);
+			SpaceBox<dim,St> sp_g = dec.getSubDomainWithGhost(i);
+
+			// Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
+			SpaceBox<dim,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp);
+			SpaceBox<dim,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g);
+
+			//! Save the origin of the sub-domain of the local grid
+			gdb_ext.last().origin = sp_tg.getP1();
+
+			// save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning)
+			// and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate
+			gdb_ext.last().Dbox = sp_t;
+			gdb_ext.last().Dbox -= sp_tg.getP1();
+
+			// center to zero
+			sp_tg -= sp_tg.getP1();
+
+			// Get the size of the local grid
+			for (size_t i = 0 ; i < dim ; i++) {l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;}
+
+			// Set the dimensions of the local grid
+			loc_grid.get(i).resize(l_res);
+		}
+	}
+
 public:
 
+	// Which kind of grid the structure store
+	typedef device_grid d_grid;
+
 	//! constructor
 	grid_dist_id(Vcluster v_cl, Decomposition & dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,T> & ghost)
-	:domain(domain),ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec)
+	:domain(domain),ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec),ginfo(g_sz),ginfo_v(g_sz)
 	{
 		check_size(g_sz);
 
@@ -397,7 +455,7 @@ public:
 	 *
 	 */
 	grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g)
-	:domain(domain),ghost(g),dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster)
+	:domain(domain),ghost(g),dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz)
 	{
 		// check that the grid has valid size
 		check_size(g_sz);
@@ -433,6 +491,26 @@ public:
 		dec.calculateGhostBoxes();
 	}
 
+	/*! \brief Get an object containing the grid informations
+	 *
+	 * \return an information object about this grid
+	 *
+	 */
+	const grid_sm<dim,T> & getGridInfo()
+	{
+		return ginfo;
+	}
+
+	/*! \brief Get an object containing the grid informations without type
+	 *
+	 * \return an information object about this grid
+	 *
+	 */
+	const grid_sm<dim,void> & getGridInfoVoid()
+	{
+		return ginfo_v;
+	}
+
 	/*! \brief Get the object that store the information about the decomposition
 	 *
 	 * \return the decomposition object
@@ -453,55 +531,6 @@ public:
 		return cd_sm;
 	}
 
-	/*! \brief Create the grids on memory
-	 *
-	 */
-	void Create()
-	{
-		Box<dim,St> g_rnd_box;
-		for (size_t i = 0 ; i < dim ; i++)	{g_rnd_box.setHigh(i,0.5); g_rnd_box.setLow(i,-0.5);}
-
-		// Get the number of local grid needed
-		size_t n_grid = dec.getNLocalHyperCube();
-
-		// 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[dim];
-
-		// Allocate the grids
-		for (size_t i = 0 ; i < n_grid ; i++)
-		{
-			gdb_ext.add();
-
-			// Get the local hyper-cube
-			SpaceBox<dim,St> sp = dec.getLocalHyperCube(i);
-			SpaceBox<dim,St> sp_g = dec.getSubDomainWithGhost(i);
-
-			// Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
-			SpaceBox<dim,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp);
-			SpaceBox<dim,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g);
-
-			//! Save the origin of the sub-domain of the local grid
-			gdb_ext.last().origin = sp_tg.getP1();
-
-			// save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning)
-			// and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate
-			gdb_ext.last().Dbox = sp_t;
-			gdb_ext.last().Dbox -= sp_tg.getP1();
-
-			// center to zero
-			sp_tg -= sp_tg.getP1();
-
-			// Get the size of the local grid
-			for (size_t i = 0 ; i < dim ; i++) {l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;}
-
-			// Set the dimensions of the local grid
-			loc_grid.get(i).resize(l_res);
-		}
-	}
-
 	/*! \brief Check that the global grid key is inside the grid domain
 	 *
 	 * \return true if is inside
diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp
index ca6d7fba04c2bfa26bb503627b7db8fe513253d2..73e04ad426f50beff419e3a11ececede901dd525 100644
--- a/src/Grid/grid_dist_id_unit_test.hpp
+++ b/src/Grid/grid_dist_id_unit_test.hpp
@@ -110,18 +110,21 @@ void Test2D_sub(const Box<2,float> & domain, long int k)
 		bool val = g_dist.getDecomposition().check_consistency();
 		BOOST_REQUIRE_EQUAL(val,true);
 
+		size_t count;
+
 		// Grid sm
 		grid_sm<2,void> info(sz);
 
-		// get the domain iterator
-		size_t count = 0;
-
+		{
 		//! [Usage of a sub_grid iterator]
 
 		grid_key_dx<2> one(1,1);
 		grid_key_dx<2> one_end(k-2,k-2);
 
 		bool check = true;
+		count = 0;
+
+		// get the sub-domain iterator
 		auto dom = g_dist.getSubDomainIterator(one,one_end);
 
 		while (dom.isNext())
@@ -145,6 +148,8 @@ void Test2D_sub(const Box<2,float> & domain, long int k)
 
 		//! [Usage of a sub_grid iterator]
 
+		}
+
 		// Get the virtual cluster machine
 		Vcluster & vcl = g_dist.getVC();
 
@@ -154,6 +159,45 @@ void Test2D_sub(const Box<2,float> & domain, long int k)
 
 		// Check
 		BOOST_REQUIRE_EQUAL(count,(k-2)*(k-2));
+
+		// check with a 1x1 square
+
+		{
+
+		grid_key_dx<2> one(k/2,k/2);
+		grid_key_dx<2> one_end(k/2,k/2);
+
+		count = 0;
+
+		// get the sub-domain iterator
+		auto dom = g_dist.getSubDomainIterator(one,one_end);
+
+		while (dom.isNext())
+		{
+			auto key = dom.get();
+			auto key_g = g_dist.getGKey(key);
+
+			// key_g
+			BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
+			BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
+
+			key_s_it = dom.getGKey(key);
+
+			BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
+			BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
+
+			// Count the point
+			count++;
+
+			++dom;
+		}
+
+		// reduce
+		vcl.sum(count);
+		vcl.execute();
+
+		BOOST_REQUIRE_EQUAL(count,1);
+		}
 	}
 }
 
@@ -304,7 +348,11 @@ void Test3D_sub(const Box<3,float> & domain, long int k)
 		// get the domain iterator
 		size_t count = 0;
 
-		auto dom = g_dist.getDomainIterator();
+		grid_key_dx<3> one(1,1,1);
+		grid_key_dx<3> one_end(k-2,k-2,k-2);
+
+		// Sub-domain iterator
+		auto dom = g_dist.getSubDomainIterator(one,one_end);
 
 		while (dom.isNext())
 		{
@@ -327,51 +375,47 @@ void Test3D_sub(const Box<3,float> & domain, long int k)
 		vcl.execute();
 
 		// Check
-		BOOST_REQUIRE_EQUAL(count,k*k*k);
-
-		bool match = true;
+		BOOST_REQUIRE_EQUAL(count,(k-2)*(k-2)*(k-2));
 
-		auto dom2 = g_dist.getDomainIterator();
-
-		// check that the grid store the correct information
-		while (dom2.isNext())
+		// check with a 1x1x1 square
 		{
-			auto key = dom2.get();
-			auto key_g = g_dist.getGKey(key);
-
-			match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
 
-			++dom2;
-		}
+		grid_key_dx<3> one(k/2,k/2,k/2);
+		grid_key_dx<3> one_end(k/2,k/2,k/2);
 
-		BOOST_REQUIRE_EQUAL(match,true);
+		count = 0;
 
-		//! [Synchronize the ghost and check the information]
+		// get the sub-domain iterator
+		auto dom = g_dist.getSubDomainIterator(one,one_end);
 
-		g_dist.template ghost_get<0>();
+		while (dom.isNext())
+		{
+			auto key = dom.get();
+			auto key_g = g_dist.getGKey(key);
 
-		// check that the communication is correctly completed
+			// key_g
+			BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
+			BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
+			BOOST_REQUIRE_EQUAL(key_g.get(2),k/2);
 
-		auto domg = g_dist.getDomainGhostIterator();
+			auto key_s_it = dom.getGKey(key);
 
-		// check that the grid with the ghost past store the correct information
-		while (domg.isNext())
-		{
-			auto key = domg.get();
-			auto key_g = g_dist.getGKey(key);
+			BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
+			BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
+			BOOST_REQUIRE_EQUAL(key_g.get(2),key_s_it.get(2));
 
-			// In this case the boundary condition are non periodic
-			if (g_dist.isInside(key_g))
-			{
-				match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
-			}
+			// Count the point
+			count++;
 
-			++domg;
+			++dom;
 		}
 
-		BOOST_REQUIRE_EQUAL(match,true);
+		// reduce
+		vcl.sum(count);
+		vcl.execute();
 
-		//! [Synchronize the ghost and check the information]
+		BOOST_REQUIRE_EQUAL(count,1);
+		}
 	}
 }