diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index db6f8058fc2bfc3a6f6e7eee9c04e2319d175761..7202791d8ef5320b38ceef7bc9e789589dea9788 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -20,6 +20,7 @@
 #include "Decomposition/CartDecomposition.hpp"
 #include "data_type/aggregate.hpp"
 #include "hdf5.h"
+#include "grid_dist_id_comm.hpp"
 
 //! Internal ghost box sent to construct external ghost box into the other processors
 template<unsigned int dim>
@@ -64,7 +65,7 @@ struct Box_fix
  *
  */
 template<unsigned int dim, typename St, typename T, typename Decomposition = CartDecomposition<dim,St>,typename Memory=HeapMemory , typename device_grid=grid_cpu<dim,T> >
-class grid_dist_id
+class grid_dist_id : public grid_dist_id_comm<dim,St,T,Decomposition,Memory,device_grid>
 {
 	//! Domain
 	Box<dim,St> domain;
@@ -75,12 +76,18 @@ class grid_dist_id
 	//! Local grids
 	openfpm::vector<device_grid> loc_grid;
 
+	//! Old (before loading) local grids
+	//openfpm::vector<device_grid> loc_grid_old;
+
 	//! Space Decomposition
 	Decomposition dec;
 
 	//! Extension of each grid: Domain and ghost + domain
 	openfpm::vector<GBoxes<device_grid::dims>> gdb_ext;
 
+	//! Extension of each old grid (before loading): Domain and ghost + domain
+	//openfpm::vector<GBoxes<device_grid::dims>> gdb_ext_old;
+
 	//! Size of the grid on each dimension
 	size_t g_sz[dim];
 
@@ -1563,19 +1570,20 @@ public:
 	 *
 	 *
 	 */
-	void map()
+	void map(openfpm::vector<SpaceBox<dim, T>> & sub_domains_old)
 	{
-
+		this->template map_(sub_domains_old,loc_grid,gdb_ext);
 	}
 
+
 	inline void save(const std::string & filename) const
 	{
 		//Pack_request vector
 		size_t req = 0;
 
 		//Pack request
-		//Packer<decltype(dec.getSubDomains()),HeapMemory>::packRequest(dec.getSubDomains(),req);
-		//Packer<decltype(ginfo),HeapMemory>::packRequest(ginfo,req);
+		Packer<decltype(dec.getSubDomains()),HeapMemory>::packRequest(dec.getSubDomains(),req);
+		Packer<decltype(loc_grid),HeapMemory>::packRequest(loc_grid,req);
 		Packer<decltype(gdb_ext),HeapMemory>::packRequest(gdb_ext,req);
 
 		std::cout << "Req: " << req << std::endl;
@@ -1590,8 +1598,8 @@ public:
 
 		Pack_stat sts;
 
-		//Packer<decltype(dec.getSubDomains()),HeapMemory>::pack(mem,dec.getSubDomains(),sts);
-		//Packer<decltype(ginfo),HeapMemory>::pack(mem,ginfo,sts);
+		Packer<decltype(dec.getSubDomains()),HeapMemory>::pack(mem,dec.getSubDomains(),sts);
+		Packer<decltype(loc_grid),HeapMemory>::pack(mem,loc_grid,sts);
 		Packer<decltype(gdb_ext),HeapMemory>::pack(mem,gdb_ext,sts);
 
 	    /*****************************************************************
@@ -1935,13 +1943,19 @@ public:
 
 		Unpack_stat ps;
 
-		//Unpacker<decltype(dec.getSubDomains()),HeapMemory>::unpack(mem,dec.getSubDomains(),ps);
+
+		//! the set of all old (before loading) local sub-domain as vector
+		openfpm::vector<SpaceBox<dim, T>> sub_domains_old;
+
+		Unpacker<decltype(sub_domains_old),HeapMemory>::unpack(mem,sub_domains_old,ps);
+		Unpacker<decltype(loc_grid),HeapMemory>::unpack(mem,loc_grid,ps);
 		Unpacker<decltype(gdb_ext),HeapMemory>::unpack(mem,gdb_ext,ps);
 
 		mem.decRef();
 		delete &mem;
 
-		//map();
+		// Map the distributed grid
+		map(sub_domains_old);
 	}
 
 	//! Define friend classes
diff --git a/src/Grid/grid_dist_id_HDF5_chckpnt_restart_test.hpp b/src/Grid/grid_dist_id_HDF5_chckpnt_restart_test.hpp
index 1a53134f54624a62629c3dcc00019fadc66c9428..3fc2c7300ca2feeac91205538879ba3c47b7904d 100644
--- a/src/Grid/grid_dist_id_HDF5_chckpnt_restart_test.hpp
+++ b/src/Grid/grid_dist_id_HDF5_chckpnt_restart_test.hpp
@@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_hdf5_save_test )
 	size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
 
 	// Domain
-	Box<3,float> domain({-0.3,-0.3,-0.3},{1.0,1.0,1.0});
+	Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
 
 	Vcluster & v_cl = create_vcluster();
 
@@ -77,7 +77,6 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_hdf5_save_test )
 		vol += g_box.getVolumeKey();
 	}
 
-
 	// Save the vector
     g_dist.save("grid_dist_id.h5");
 }
@@ -94,7 +93,7 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_hdf5_load_test )
 	size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
 
 	// Domain
-	Box<3,float> domain({-0.3,-0.3,-0.3},{1.0,1.0,1.0});
+	Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
 
 	Vcluster & v_cl = create_vcluster();
 
diff --git a/src/Grid/grid_dist_id_comm.hpp b/src/Grid/grid_dist_id_comm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f630ac5ea47d0b3fabcfa8acb0f6d34c7064aee
--- /dev/null
+++ b/src/Grid/grid_dist_id_comm.hpp
@@ -0,0 +1,229 @@
+/*
+ * grid_dist_id_comm.hpp
+ *
+ *  Created on: Nov 13, 2016
+ *      Author: yaroslav
+ */
+
+#ifndef SRC_GRID_GRID_DIST_ID_COMM_HPP_
+#define SRC_GRID_GRID_DIST_ID_COMM_HPP_
+
+#include "Vector/vector_dist_ofb.hpp"
+
+/*! \brief This class is an helper for the communication of grid_dist_id
+ *
+ * \tparam dim Dimensionality of the grid
+ * \tparam St Type of space where the grid is living
+ * \tparam T object the grid is storing
+ * \tparam Decomposition Class that decompose the grid for example CartDecomposition
+ * \tparam Memory Is the allocator
+ * \tparam device_grid of base structure is going to store the data
+ *
+ * \see grid_dist_id
+ *
+ */
+
+template<unsigned int dim, typename St, typename T, typename Decomposition = CartDecomposition<dim,St>,typename Memory=HeapMemory , typename device_grid=grid_cpu<dim,T> >
+class grid_dist_id_comm
+{
+	//! VCluster
+	Vcluster & v_cl;
+
+	//! Domain decomposition
+	Decomposition dec;
+
+	//! Maps the processor id with the communication request into map procedure
+	openfpm::vector<size_t> p_map_req;
+
+	//! Stores the list of processors that communicate with us (local processor)
+	openfpm::vector<size_t> prc_recv_map;
+
+	//! Stores the size of the elements added for each processor that communicate with us (local processor)
+	openfpm::vector<size_t> recv_sz_map;
+
+	//! For each near processor, outgoing Box
+	//! \warning m_oBox is assumed to be an ordered list
+	//! first id point Box
+	//! second id is the processor id
+	openfpm::vector<aggregate<Box<dim,St>,size_t>> m_oBox;
+
+public:
+
+	//! It process one particle
+	template<typename T1, typename T2, typename T3, typename T4> inline void process_map_particle(size_t i, long int & end, long int & id_end, T1 & m_pos, T2 & m_prp, T3 & v_pos, T4 & v_prp, openfpm::vector<size_t> & cnt)
+	{
+/*
+		long int prc_id = m_oBox.template get<1>(i);
+		size_t id = m_oBox.template get<0>(i);
+
+		if (prc_id >= 0)
+		{
+			size_t lbl = p_map_req.get(prc_id);
+
+			m_pos.get(lbl).set(cnt.get(lbl), v_pos.get(id));
+
+			cnt.get(lbl)++;
+
+			// swap the particle
+			long int id_valid = get_end_valid(end,id_end);
+
+			if (id_valid > 0 && (long int)id < id_valid)
+			{
+				v_pos.set(id,v_pos.get(id_valid));
+				v_prp.set(id,v_prp.get(id_valid));
+			}
+		}
+		else
+		{
+			// swap the particle
+			long int id_valid = get_end_valid(end,id_end);
+
+			if (id_valid > 0 && (long int)id < id_valid)
+			{
+				v_pos.set(id,v_pos.get(id_valid));
+				v_prp.set(id,v_prp.get(id_valid));
+			}
+		}
+*/
+	}
+
+	/*! \brief Allocates and fills the send buffer for the map function
+	 *
+	 * \param v_pos vector of particle positions
+	 * \param v_prp vector of particle properties
+	 * \param prc_r List of processor rank involved in the send
+	 * \param prc_sz_r For each processor in the list the size of the message to send
+	 * \param pb send buffer
+	 *
+	 */
+	void fill_send_map_buf(openfpm::vector<device_grid> & loc_grid, openfpm::vector<size_t> & prc_sz_r, openfpm::vector<openfpm::vector<Box<dim,St>>> & m_box)
+	{
+		m_box.resize(prc_sz_r.size());
+		openfpm::vector<size_t> cnt(prc_sz_r.size());
+
+		for (size_t i = 0; i < prc_sz_r.size(); i++)
+		{
+			// set the size and allocate, using mem warant that pos and prp is contiguous
+			m_box.get(i).resize(prc_sz_r.get(i));
+			cnt.get(i) = 0;
+		}
+/*
+		// end vector point
+		long int id_end = v_pos.size();
+
+		// end opart point
+		long int end = m_opart.size()-1;
+
+		// Run through all the particles and fill the sending buffer
+		for (size_t i = 0; i < m_opart.size(); i++)
+		{
+			process_map_particle<proc_with_prp<prp_object,prp...>>(i,end,id_end,m_pos,m_prp,v_pos,v_prp,cnt);
+		}
+
+		v_pos.resize(v_pos.size() - m_opart.size());
+*/
+	}
+
+	/*! \brief Label particles for mappings
+	 *
+	 * \param v_pos vector of particle positions
+	 * \param lbl_p Particle labeled
+	 * \param prc_sz For each processor the number of particles to send
+	 * \param opart id of the particles to send
+	 *
+	 */
+	void labelIntersectionGridsProcessor(openfpm::vector<SpaceBox<dim, T>> & sub_domains_old, openfpm::vector<device_grid> & loc_grid, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext, openfpm::vector<aggregate<Box<dim,St>,size_t>> & lbl_b, openfpm::vector<size_t> & prc_sz)
+	{
+		// reset lbl_b
+		lbl_b.clear();
+
+		// resize the label buffer
+		prc_sz.resize(v_cl.getProcessingUnits());
+
+		// Label all the intersection boxes with the processor id where they should go
+		for (size_t i = 0; i < dec.getNSubDomain(); i++)
+		{
+			for (size_t j = 0; j < sub_domains_old.size(); j++)
+			{
+				size_t p_id = 0;
+
+				Box<dim,St> inte_box;
+				bool intersect = dec.getSubDomain(i).Intersect(sub_domains_old.get(j), inte_box);
+
+				if (intersect == true)
+				{
+					p_id = dec.processorID(inte_box.rnd());
+					prc_sz.get(p_id)++;
+
+					lbl_b.add();
+					////////////////////
+					lbl_b.last().template get<0>() = inte_box;
+					////////////////////
+					lbl_b.last().template get<1>() = p_id;
+				}
+			}
+		}
+	}
+
+	/*! \brief Moves all the grids that does not belong to the local processor to the respective processor
+	 *
+	 * \tparam out of bound policy it specify what to do when the particles are detected out of bound
+	 *
+	 * In general this function is called after moving the particles to move the
+	 * elements out the local processor. Or just after initialization if each processor
+	 * contain non local particles
+	 *
+	 * \param v_pos vector of particle positions
+	 * \param v_prp vector of particle properties
+	 * \param g_m ghost marker
+	 *
+	 */
+	void map_(openfpm::vector<SpaceBox<dim, T>> & sub_domains_old, openfpm::vector<device_grid> & loc_grid, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
+	{
+		// Processor communication size
+		openfpm::vector<size_t> prc_sz(v_cl.getProcessingUnits());
+
+		// Contains the processor id of each grid (basically where they have to go)
+		labelIntersectionGridsProcessor(sub_domains_old,loc_grid,gdb_ext,m_oBox,prc_sz);
+
+		// Calculate the sending buffer size for each processor, put this information in
+		// a contiguous buffer
+		p_map_req.resize(v_cl.getProcessingUnits());
+
+		// Vector of number of boxes for each involved processor
+		openfpm::vector<size_t> prc_sz_r;
+		// Vector of ranks of involved processors
+		openfpm::vector<size_t> prc_r;
+
+		for (size_t i = 0; i < v_cl.getProcessingUnits(); i++)
+		{
+			if (prc_sz.get(i) != 0)
+			{
+				p_map_req.get(i) = prc_r.size();
+				prc_r.add(i);
+				prc_sz_r.add(prc_sz.get(i));
+			}
+		}
+
+		//! Grids vector
+		openfpm::vector<openfpm::vector<Box<dim,St>>> m_box;
+
+		fill_send_map_buf(loc_grid, prc_sz_r, m_box);
+
+		v_cl.SSendRecv(m_box,loc_grid,prc_r,prc_recv_map,recv_sz_map);
+	}
+
+	/*! \brief Constructor
+	 *
+	 * \param dec Domain decompositon
+	 *
+	 */
+	grid_dist_id_comm(const Decomposition & dec)
+	:v_cl(create_vcluster()),dec(dec)
+	{
+
+	}
+};
+
+
+#endif /* SRC_GRID_GRID_DIST_ID_COMM_HPP_ */