diff --git a/example/Vector/0_simple/main.cpp b/example/Vector/0_simple/main.cpp
index 0e6a334477539f0632710a74a26b19a9236587e4..a2c9b7b250983ac08a397c71c3e9d62c88ff1323 100644
--- a/example/Vector/0_simple/main.cpp
+++ b/example/Vector/0_simple/main.cpp
@@ -9,6 +9,7 @@
  * \subpage Vector_4_cp
  * \subpage Vector_4_mp_cl
  * \subpage Vector_5_md_vl_sym
+ * \subpage Vector_5_md_vl_sym_crs
  * \subpage Vector_6_complex_usage
  *
  */
diff --git a/example/Vector/5_molecular_dynamic_sym_crs/Makefile b/example/Vector/5_molecular_dynamic_sym_crs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..cf0391fab74d27ace055d5904d8df2c180b2266d
--- /dev/null
+++ b/example/Vector/5_molecular_dynamic_sym_crs/Makefile
@@ -0,0 +1,24 @@
+include ../../example.mk
+
+CC=mpic++
+
+LDIR =
+
+OBJ_DORD = main.o
+
+all: md_sym
+
+%.o: %.cpp
+	$(CC) -O3 -g -c --std=c++11 $(OPT) -o $@ $< $(INCLUDE_PATH)
+
+md_sym: $(OBJ_DORD)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
+
+run: md_sym
+	mpirun -np 3 ./md_sym
+
+.PHONY: clean all run
+
+clean:
+	rm -f *.o *~ core md_sym
+
diff --git a/example/Vector/5_molecular_dynamic_sym_crs/config.cfg b/example/Vector/5_molecular_dynamic_sym_crs/config.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..1eecbac3577c765edca7f90cf5f61cfb6b9f4880
--- /dev/null
+++ b/example/Vector/5_molecular_dynamic_sym_crs/config.cfg
@@ -0,0 +1,2 @@
+[pack]
+files = main.cpp Makefile
diff --git a/example/Vector/5_molecular_dynamic_sym_crs/main.cpp b/example/Vector/5_molecular_dynamic_sym_crs/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fe6bec6ba6215df5bab4fa418542dc06edd351a5
--- /dev/null
+++ b/example/Vector/5_molecular_dynamic_sym_crs/main.cpp
@@ -0,0 +1,571 @@
+#include "Vector/vector_dist.hpp"
+#include "Decomposition/CartDecomposition.hpp"
+#include "data_type/aggregate.hpp"
+#include "Plot/GoogleChart.hpp"
+#include "Plot/util.hpp"
+#include "timer.hpp"
+
+/*!
+ * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+ *
+ *
+ * # Molecular dynamic with symmetric interactions (Crossing scheme)# {#md_e5_sym_crs}
+ *
+ * In a previous example we show how to build a parallel molecular dynamic simulation in the case
+ * of symmetric interaction.
+ *
+ * \see \ref Vector_5_md_vl_sym
+ *
+ * Symmetric interaction has one big advantage to cut by half the computation.
+ * Unfortunately has also one disadvantage. In the standard way it increase communication overhead.
+ * This effect can be seen in a simple way consider the non-symmetric case.
+ *
+ * \verbatim
+
+    Non-symmetric                  Symmetric
+
++-----------------+             +-----------------+         +-----------------+
+|XXXXXXXXXXXXXXXXX|             |XXXXXXXXXXXXXXXXX|         |XXXXXXXXXXXXXXXXX|
+|XX+-----------+XX|             |XX+-----------+XX|         |XX+-----------+XX|
+|XX|           |XX|             |XX|           |XX|         |XX|           |XX|
+|XX|           |XX|             |XX|           |XX|         |XX|           |XX|
+|XX|           |XX|             |XX|           |XX|      +  |XX|           |XX|
+|XX|           |XX|             |XX|           |XX|         |XX|           |XX|
+|XX|           |XX|             |XX|           |XX|         |XX|           |XX|
+|XX|           |XX|             |XX|           |XX|         |XX|           |XX|
+|XX+-----------+XX|             +-----------------+         +-----------------+
+|XXXXXXXXXXXXXXXXX|
++-----------------+                  ghost_get                     ghost_put
+
+     ghost_get
+
+
+ * \endverbatim
+ *
+ * In the non-symmetric case we do a ghost-get communicating the area indicated
+ * with "X". After this we are able to calculate the forces inside the box.
+ * In the case of normal symmetric like explained in the previous example the first
+ * ghost_get communicate the area indicated by X and the ghost_put communicate
+ * an equivalent area. This mean that The communication area for the non-symmetric
+ * is smaller than the symmetric one. This mean that overall the standard symmetric
+ * requires more communication. In order to reduce the communication of the standard
+ * symmetric we can use the crossing scheme. The crossing scheme do the following
+ *
+ * \verbatim
+
+
+   1 2 3              1 2      3
+     X 4              X 3    + X 4
+
+ \endverbatim
+ *
+ * If X is the Cell and the numbers are the neighborhood cells, the concept of the crossing scheme is to
+ * take the interaction X with "1" and shift by one to the right. This mean that for each cell "X"
+ * in our domain we have to do the interaction (X-1),(X-2),(X-3),(3,4). Note that in the case of standard
+ * symmetric, all the interactions are in the top,left and right cells of the domain cells. Because of this
+ * we can eliminate the bottom part in the ghost_get and in the subsequent ghost_put. In the case of
+ * the crossing scheme we have only interaction with the top and right cells, so we do not need the
+ *  bottom and left part of the ghost.
+ *
+ *  \verbatim
+
+ Symmetric   crs
+
+	+--------------+            +--------------+
+	|XXXXXXXXXXXXXX|            |XXXXXXXXXXXXXX|
+	+-----------+XX|            +-----------+XX|
+	|           |XX|            |           |XX|
+	|           |XX|            |           |XX|
+	|           |XX|      +     |           |XX|
+	|           |XX|            |           |XX|
+	|           |XX|            |           |XX|
+	|           |XX|            |           |XX|
+	+--------------+            +--------------+
+
+	  ghost_get                     ghost_put
+
+
+ \endverbatim
+ *
+ *   In this example we modify the molecular dynamic example to use
+ *  this scheme.
+ *
+ */
+
+//! \cond [constants] \endcond
+
+constexpr int velocity = 0;
+constexpr int force = 1;
+
+//! \cond [constants] \endcond
+
+/*!
+ *
+ * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+ *
+ * ## Calculate forces ## {#md_e5_calc_force_crs}
+ *
+ * In this function we calculate the forces between particles. It require the vector of particles
+ * the Verlet-list and sigma factor for the Lennard-Jhones potential. The function is exactly the same
+ * as the normal symmetric
+ *
+ * \see \ref md_e5_sym_expl
+ *
+ * with the following changes
+ *
+ *
+ * * We use a different particle iterator compared to the getDomainIterator() this because the
+ *   the particles to iterate are different from the simple domain particles.
+ *
+ *
+ * The calculation is the same as the normal symmetric case
+ *
+ *
+ * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp calc forces vl
+ *
+ */
+
+//! \cond [calc forces vl] \endcond
+
+void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, VerletList<3, double, FAST, shift<3, double> > & NN, double sigma12, double sigma6, double r_cut)
+{
+	// Reset force on the ghost
+
+	auto itg = vd.getDomainAndGhostIterator();
+
+	while (itg.isNext())
+	{
+		auto p = itg.get();
+
+		// Reset force
+		vd.getProp<force>(p)[0] = 0.0;
+		vd.getProp<force>(p)[1] = 0.0;
+		vd.getProp<force>(p)[2] = 0.0;
+
+		++itg;
+	}
+
+	//! \cond [real and ghost] \endcond
+
+	// Get an iterator over particles
+	auto it2 = vd.getParticleIteratorCRS(NN.getInternalCellList());
+
+	//! \cond [real and ghost] \endcond
+
+	// For each particle p ...
+	while (it2.isNext())
+	{
+		// ... get the particle p
+		auto p = it2.get();
+
+		// Get the position xp of the particle
+		Point<3,double> xp = vd.getPos(p);
+
+		// Get an iterator over the neighborhood particles of p
+		// Note that in case of symmetric
+		auto Np = NN.getNNIterator<NO_CHECK>(p);
+
+		// For each neighborhood particle ...
+		while (Np.isNext())
+		{
+			// ... q
+			auto q = Np.get();
+
+			// if (p == q) skip this particle
+			if (q == p)	{++Np; continue;};
+
+			// Get the position of q
+			Point<3,double> xq = vd.getPos(q);
+
+			// Get the distance between p and q
+			Point<3,double> r = xp - xq;
+
+			// take the norm of this vector
+			double rn = norm2(r);
+
+			if (rn > r_cut * r_cut) {++Np;continue;}
+
+			// Calculate the force, using pow is slower
+			Point<3,double> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) -  sigma6 / (rn*rn*rn*rn)) * r;
+
+			// we sum the force produced by q on p
+			vd.template getProp<force>(p)[0] += f.get(0);
+			vd.template getProp<force>(p)[1] += f.get(1);
+			vd.template getProp<force>(p)[2] += f.get(2);
+
+			//! \cond [add to q] \endcond
+
+			// we sum the force produced by p on q
+			vd.template getProp<force>(q)[0] -= f.get(0);
+			vd.template getProp<force>(q)[1] -= f.get(1);
+			vd.template getProp<force>(q)[2] -= f.get(2);
+
+			//! \cond [add to q] \endcond
+
+			// Next neighborhood
+			++Np;
+		}
+
+		// Next particle
+		++it2;
+	}
+
+	//! \cond [ghost_put] \endcond
+
+	// Sum the contribution to the real particles
+	vd.ghost_put<add_,force>();
+
+	//! \cond [ghost_put] \endcond
+}
+
+//! \cond [calc forces vl] \endcond
+
+
+/*!
+ *
+ * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+ *
+ * ## Calculate energy ## {#md_e5_calc_one_crs}
+ *
+ * For the energy we use symmetric verlet-list in the same way as we did in the previous example.
+ * The changes are the following.
+ *
+ * * We use a different particle iterator compared to the getDomainIterator() this because the
+ *   the particles to iterate are different from the simple domain particles.
+ *
+ * * Because we are iterating domain particles and ghost particles. For the Kinetic energy we have
+ *   to filter-out ghost particles
+ *
+ * \snippet Vector/5_molecular_dynamic_sym/main.cpp calc energy vl
+ *
+ */
+
+//! \cond [calc energy vl] \endcond
+
+double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, VerletList<3, double, FAST, shift<3, double> > & NN, double sigma12, double sigma6, double r_cut)
+{
+	double E = 0.0;
+
+	double rc = r_cut*r_cut;
+	double shift = 4.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
+
+	// Get an iterator over particles
+	auto it2 = vd.getParticleIteratorCRS(NN.getInternalCellList());
+
+	// For each particle ...
+	while (it2.isNext())
+	{
+		// ... p
+		auto p = it2.get();
+
+		// Get the position of the particle p
+		Point<3,double> xp = vd.getPos(p);
+
+		// Get an iterator over the neighborhood particles of p
+		auto Np = NN.getNNIterator<NO_CHECK>(p);
+
+		double Ep = E;
+
+		// For each neighborhood of the particle p
+		while (Np.isNext())
+		{
+			// Neighborhood particle q
+			auto q = Np.get();
+
+			// if p == q skip this particle
+			if (q == p)	{++Np; continue;};
+
+			// Get position of the particle q
+			Point<3,double> xq = vd.getPos(q);
+
+			// take the normalized direction
+			double rn = norm2(xp - xq);
+
+			if (rn >= r_cut*r_cut)	{++Np;continue;}
+
+			// potential energy (using pow is slower)
+			E += 4.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) - shift;
+
+			// Next neighborhood
+			++Np;
+		}
+
+		// To note that the crossing scheme go across the domain particles +
+		// some ghost particles. This mean that we have to filter out the ghost
+		// particles otherwise we count double energies
+		//
+		if (p < vd.size_local())
+		{
+			// Kinetic energy of the particle given by its actual speed
+			E += (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
+					vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
+					vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
+		}
+
+		// Next Particle
+		++it2;
+	}
+
+	// Calculated energy
+	return E;
+}
+
+//! \cond [calc energy vl] \endcond
+
+int main(int argc, char* argv[])
+{
+	/*!
+	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+	 *
+	 * ## Simulation ## {#md_e5_sym_sim_crs}
+	 *
+	 * The simulation is equal to the simulation explained in the example molecular dynamic
+	 *
+	 * \see \ref md_e5_sym
+	 *
+	 * The difference is that we create a symmetric Verlet-list for crossing scheme instead of a normal one
+	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp sim verlet
+	 *
+	 * The rest of the code remain unchanged
+	 *
+	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp simulation
+	 *
+	 */
+
+	//! \cond [simulation] \endcond
+
+	double dt = 0.00025;
+	double sigma = 0.1;
+	double r_cut = 3.0*sigma;
+	double r_gskin = 1.3*r_cut;
+	double sigma12 = pow(sigma,12);
+	double sigma6 = pow(sigma,6);
+
+	openfpm::vector<double> x;
+	openfpm::vector<openfpm::vector<double>> y;
+
+	openfpm_init(&argc,&argv);
+	Vcluster & v_cl = create_vcluster();
+
+	// we will use it do place particles on a 10x10x10 Grid like
+	size_t sz[3] = {10,10,10};
+
+	// domain
+	Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
+
+	// Boundary conditions
+	size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
+
+	// ghost, big enough to contain the interaction radius
+	Ghost<3,float> ghost(r_gskin);
+	ghost.setLow(0,0.0);
+	ghost.setLow(1,0.0);
+	ghost.setLow(2,0.0);
+
+	vector_dist<3,double, aggregate<double[3],double[3]> > vd(0,box,bc,ghost,BIND_DEC_TO_GHOST);
+
+	size_t k = 0;
+	size_t start = vd.accum();
+
+	auto it = vd.getGridIterator(sz);
+
+	while (it.isNext())
+	{
+		vd.add();
+
+		auto key = it.get();
+
+		vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
+		vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
+		vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);
+
+		vd.template getLastProp<velocity>()[0] = 0.0;
+		vd.template getLastProp<velocity>()[1] = 0.0;
+		vd.template getLastProp<velocity>()[2] = 0.0;
+
+		vd.template getLastProp<force>()[0] = 0.0;
+		vd.template getLastProp<force>()[1] = 0.0;
+		vd.template getLastProp<force>()[2] = 0.0;
+
+		k++;
+		++it;
+	}
+
+	vd.map();
+	vd.ghost_get<>();
+
+	timer tsim;
+	tsim.start();
+
+	//! \cond [sim verlet] \endcond
+
+	// Get the Cell list structure
+	auto NN = vd.getVerletCrs(r_gskin);;
+
+	//! \cond [sim verlet] \endcond
+
+	// calculate forces
+	calc_forces(vd,NN,sigma12,sigma6,r_cut);
+	unsigned long int f = 0;
+
+	int cnt = 0;
+	double max_disp = 0.0;
+
+	// MD time stepping
+	for (size_t i = 0; i < 10000 ; i++)
+	{
+		// Get the iterator
+		auto it3 = vd.getDomainIterator();
+
+		double max_displ = 0.0;
+
+		// integrate velicity and space based on the calculated forces (Step1)
+		while (it3.isNext())
+		{
+			auto p = it3.get();
+
+			// here we calculate v(tn + 0.5)
+			vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
+			vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
+			vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
+
+			Point<3,double> disp({vd.template getProp<velocity>(p)[0]*dt,vd.template getProp<velocity>(p)[1]*dt,vd.template getProp<velocity>(p)[2]*dt});
+
+			// here we calculate x(tn + 1)
+			vd.getPos(p)[0] += disp.get(0);
+			vd.getPos(p)[1] += disp.get(1);
+			vd.getPos(p)[2] += disp.get(2);
+
+			if (disp.norm() > max_displ)
+				max_displ = disp.norm();
+
+			++it3;
+		}
+
+		if (max_disp < max_displ)
+			max_disp = max_displ;
+
+		// Because we moved the particles in space we have to map them and re-sync the ghost
+		if (cnt % 10 == 0)
+		{
+			vd.map();
+			vd.template ghost_get<>();
+			// Get the Cell list structure
+			vd.updateVerlet(NN,r_gskin,VL_CRS_SYMMETRIC);
+		}
+		else
+		{
+			vd.template ghost_get<>(SKIP_LABELLING);
+		}
+
+		cnt++;
+
+		// calculate forces or a(tn + 1) Step 2
+		calc_forces(vd,NN,sigma12,sigma6,r_cut);
+
+		// Integrate the velocity Step 3
+		auto it4 = vd.getDomainIterator();
+
+		while (it4.isNext())
+		{
+			auto p = it4.get();
+
+			// here we calculate v(tn + 1)
+			vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
+			vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
+			vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
+
+			++it4;
+		}
+
+		// After every iteration collect some statistic about the confoguration
+		if (i % 100 == 0)
+		{
+			// We write the particle position for visualization (Without ghost)
+			vd.deleteGhost();
+			vd.write("particles_",f);
+
+			// we resync the ghost
+			vd.ghost_get<>();
+
+
+			// We calculate the energy
+			double energy = calc_energy(vd,NN,sigma12,sigma6,r_cut);
+			auto & vcl = create_vcluster();
+			vcl.sum(energy);
+			vcl.max(max_disp);
+			vcl.execute();
+
+			// we save the energy calculated at time step i c contain the time-step y contain the energy
+			x.add(i);
+			y.add({energy});
+
+			// We also print on terminal the value of the energy
+			// only one processor (master) write on terminal
+			if (vcl.getProcessUnitID() == 0)
+				std::cout << "Energy: " << energy << "   " << max_disp << "   " << std::endl;
+
+			max_disp = 0.0;
+
+			f++;
+		}
+	}
+
+	tsim.stop();
+	std::cout << "Time: " << tsim.getwct()  << std::endl;
+
+	//! \cond [simulation] \endcond
+
+	// Google charts options, it store the options to draw the X Y graph
+	GCoptions options;
+
+	// Title of the graph
+	options.title = std::string("Energy with time");
+
+	// Y axis name
+	options.yAxis = std::string("Energy");
+
+	// X axis name
+	options.xAxis = std::string("iteration");
+
+	// width of the line
+	options.lineWidth = 1.0;
+
+	// Object that draw the X Y graph
+	GoogleChart cg;
+
+	// Add the graph
+	// The graph that it produce is in svg format that can be opened on browser
+	cg.AddLinesGraph(x,y,options);
+
+	// Write into html format
+	cg.write("gc_plot2_out.html");
+
+	//! \cond [google chart] \endcond
+
+	/*!
+	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+	 *
+	 * ## Finalize ## {#finalize_v_e5_md_sym_crs}
+	 *
+	 *  At the very end of the program we have always to de-initialize the library
+	 *
+	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp finalize
+	 *
+	 */
+
+	//! \cond [finalize] \endcond
+
+	openfpm_finalize();
+
+	//! \cond [finalize] \endcond
+
+	/*!
+	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
+	 *
+	 * ## Full code ## {#full_code_v_e5_md_sym_crs}
+	 *
+	 * \include Vector/5_molecular_dynamic_sym_crs/main.cpp
+	 *
+	 */
+}
diff --git a/openfpm_data b/openfpm_data
index 155cc3537485efb4993a667330a01a7d2644449a..7e326c0134dedecc6cf06dfb9e3a466e66280300 160000
--- a/openfpm_data
+++ b/openfpm_data
@@ -1 +1 @@
-Subproject commit 155cc3537485efb4993a667330a01a7d2644449a
+Subproject commit 7e326c0134dedecc6cf06dfb9e3a466e66280300
diff --git a/openfpm_pdata.doc b/openfpm_pdata.doc
index 1375042ee7fb74340aa4414415ecafd645f56e6d..21a5e06b66dc77ca1b8be3e6157fc538b4f1de26 100644
--- a/openfpm_pdata.doc
+++ b/openfpm_pdata.doc
@@ -38,7 +38,7 @@ PROJECT_NAME           = "OpenFPM_pdata"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.6.0
+PROJECT_NUMBER         = 0.7.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/src/Decomposition/nn_processor.hpp b/src/Decomposition/nn_processor.hpp
index 54f3249ea23527ff52ad40b8636ea3ecd79c8e63..2bc8e30605dadebdad675366b6e2941184a6c245 100755
--- a/src/Decomposition/nn_processor.hpp
+++ b/src/Decomposition/nn_processor.hpp
@@ -623,7 +623,7 @@ public:
 
 		aBC=true;
 
-		return add_box_periodic(domain,ghost,bc);
+		add_box_periodic(domain,ghost,bc);
 	}
 
 	/*! \brief Check if the nn_prcs contain the same information
diff --git a/src/Makefile.am b/src/Makefile.am
index 04449f1ce4088cf7e3dc42c46ecd8fe26fa5ffff..b2cad2a544a2d5c45102690be9e6589d9fe5cf2c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,7 @@ pdata_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(PETSC_I
 pdata_CFLAGS = $(CUDA_CFLAGS)
 pdata_LDADD = $(LINKLIBS) -lparmetis -lmetis
 nobase_include_HEADERS = Decomposition/CartDecomposition.hpp Decomposition/CartDecomposition_ext.hpp  Decomposition/common.hpp Decomposition/Decomposition.hpp  Decomposition/ie_ghost.hpp \
-         Decomposition/nn_processor.hpp Decomposition/ie_loc_ghost.hpp Decomposition/ORB.hpp \
+         Decomposition/Domain_NN_calculator_cart.hpp Decomposition/nn_processor.hpp Decomposition/ie_loc_ghost.hpp Decomposition/ORB.hpp \
          Graph/CartesianGraphFactory.hpp \
          Grid/grid_dist_id.hpp Grid/grid_dist_id_iterator_dec.hpp Grid/grid_dist_util.hpp  Grid/grid_dist_id_iterator_sub.hpp Grid/grid_dist_id_iterator.hpp Grid/grid_dist_key.hpp Grid/staggered_dist_grid.hpp Grid/staggered_dist_grid_util.hpp Grid/staggered_dist_grid_copy.hpp \
          Vector/vector_dist_multiphase_functions.hpp Vector/vector_dist_comm.hpp Vector/vector_dist.hpp Vector/vector_dist_ofb.hpp Vector/vector_dist_iterator.hpp Vector/vector_dist_key.hpp \
diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp
index 97a433e09286ace21218022183dbf311786d765d..6080050f36d2c478ae34a5e7f2d07ada0e89f0cb 100644
--- a/src/Vector/vector_dist.hpp
+++ b/src/Vector/vector_dist.hpp
@@ -548,6 +548,43 @@ public:
 		return ver;
 	}
 
+	/*! \brief for each particle get the symmetric verlet list
+	 *
+	 * \param r_cut cut-off radius
+	 *
+	 * \return the verlet list
+	 *
+	 */
+	VerletList<dim,St,FAST,shift<dim,St> > getVerletCrs(St r_cut)
+	{
+		VerletList<dim,St,FAST,shift<dim,St>> ver;
+
+		// Processor bounding box
+		Box<dim, St> pbox = getDecomposition().getProcessorBounds();
+
+		// Initialize the verlet list
+		ver.InitializeCrs(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
+
+		// Get the internal cell list
+		auto & NN = ver.getInternalCellList();
+
+		// Shift
+		grid_key_dx<dim> cell_shift = NN.getShift();
+
+		// Shift
+		grid_key_dx<dim> shift = NN.getShift();
+
+		// Add padding
+		for (size_t i = 0 ; i < dim ; i++)
+			shift.set_d(i,shift.get(i) + NN.getPadding(i));
+
+		grid_sm<dim,void> gs = NN.getInternalGrid();
+
+		ver.createVerletCrs(r_cut,g_m,v_pos,getDecomposition().getDomainCells(shift,cell_shift,gs),getDecomposition().getAnomDomainCells(shift,cell_shift,gs));
+
+		return ver;
+	}
+
 	/*! \brief for each particle get the verlet list
 	 *
 	 * \param r_cut cut-off radius
@@ -584,7 +621,27 @@ public:
 	 */
 	void updateVerlet(VerletList<dim,St,FAST,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
 	{
-		ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
+		if (opt == VL_CRS_SYMMETRIC)
+		{
+			// Get the internal cell list
+			auto & NN = ver.getInternalCellList();
+
+			// Shift
+			grid_key_dx<dim> cell_shift = NN.getShift();
+
+			// Shift
+			grid_key_dx<dim> shift = NN.getShift();
+
+			// Add padding
+			for (size_t i = 0 ; i < dim ; i++)
+				shift.set_d(i,shift.get(i) + NN.getPadding(i));
+
+			grid_sm<dim,void> gs = NN.getInternalGrid();
+
+			ver.updateCrs(getDecomposition().getDomain(),r_cut,v_pos,g_m,getDecomposition().getDomainCells(shift,cell_shift,gs),getDecomposition().getAnomDomainCells(shift,cell_shift,gs));
+		}
+		else
+			ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
 	}
 
 	/*! \brief for each particle get the verlet list
diff --git a/src/Vector/vector_dist_cell_list_tests.hpp b/src/Vector/vector_dist_cell_list_tests.hpp
index 4328e97caf882eec0d5a76354f59b1daff2e782c..8308909df42c16493101da543a2eb10c9a1016a5 100644
--- a/src/Vector/vector_dist_cell_list_tests.hpp
+++ b/src/Vector/vector_dist_cell_list_tests.hpp
@@ -564,6 +564,10 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 
 	// ghost
 	Ghost<3,float> ghost(r_cut);
+	Ghost<3,float> ghost2(r_cut);
+	ghost2.setLow(0,0.0);
+	ghost2.setLow(1,0.0);
+	ghost2.setLow(2,0.0);
 
 	// Point and global id
 	struct point_and_gid
@@ -581,6 +585,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 
 	// Distributed vector
 	vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
+	vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
 	size_t start = vd.init_size_accum(k);
 
 	auto it = vd.getIterator();
@@ -593,19 +598,32 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 		vd.getPos(key)[1] = ud(eg);
 		vd.getPos(key)[2] = ud(eg);
 
+		vd2.getPos(key)[0] = vd.getPos(key)[0];
+		vd2.getPos(key)[1] = vd.getPos(key)[1];
+		vd2.getPos(key)[2] = vd.getPos(key)[2];
+
 		// Fill some properties randomly
 
 		vd.getProp<0>(key) = 0;
 		vd.getProp<1>(key) = 0;
 		vd.getProp<2>(key) = key.getKey() + start;
 
+		vd2.getProp<0>(key) = 0;
+		vd2.getProp<1>(key) = 0;
+		vd2.getProp<2>(key) = key.getKey() + start;
+
 		++it;
 	}
 
 	vd.map();
+	vd2.map();
 
 	// sync the ghost
 	vd.ghost_get<0,2>();
+	vd2.ghost_get<0,2>();
+
+	vd2.write("CRS_output");
+	vd2.getDecomposition().write("CRS_output_dec");
 
 	auto NN = vd.getCellList(r_cut);
 	auto p_it = vd.getDomainIterator();
@@ -653,20 +671,20 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 
 	// We now try symmetric  Cell-list
 
-	auto NN2 = vd.getCellListSym(r_cut);
+	auto NN2 = vd2.getCellListSym(r_cut);
 
 	// In case of CRS we have to iterate particles within some cells
 	// here we define whichone
-	auto p_it2 = vd.getParticleIteratorCRS(NN2);
+	auto p_it2 = vd2.getParticleIteratorCRS(NN2);
 
 	// For each particle
 	while (p_it2.isNext())
 	{
 		auto p = p_it2.get();
 
-		Point<3,float> xp = vd.getPos(p);
+		Point<3,float> xp = vd2.getPos(p);
 
-		auto Np = p_it2.getNNIteratorCSR(vd.getPosVector());
+		auto Np = p_it2.getNNIteratorCSR(vd2.getPosVector());
 
 		while (Np.isNext())
 		{
@@ -680,7 +698,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 
 			// repulsive
 
-			Point<3,float> xq = vd.getPos(q);
+			Point<3,float> xq = vd2.getPos(q);
 			Point<3,float> f = (xp - xq);
 
 			float distance = f.norm();
@@ -689,16 +707,16 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 
 			if (distance < r_cut )
 			{
-				vd.getProp<1>(p)++;
-				vd.getProp<1>(q)++;
+				vd2.getProp<1>(p)++;
+				vd2.getProp<1>(q)++;
 
-				vd.getProp<4>(p).add();
-				vd.getProp<4>(q).add();
+				vd2.getProp<4>(p).add();
+				vd2.getProp<4>(q).add();
 
-				vd.getProp<4>(p).last().xq = xq;
-				vd.getProp<4>(q).last().xq = xp;
-				vd.getProp<4>(p).last().id = vd.getProp<2>(q);
-				vd.getProp<4>(q).last().id = vd.getProp<2>(p);
+				vd2.getProp<4>(p).last().xq = xq;
+				vd2.getProp<4>(q).last().xq = xp;
+				vd2.getProp<4>(p).last().id = vd2.getProp<2>(q);
+				vd2.getProp<4>(q).last().id = vd2.getProp<2>(p);
 			}
 
 			++Np;
@@ -707,8 +725,8 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 		++p_it2;
 	}
 
-	vd.ghost_put<add_,1>();
-	vd.ghost_put<merge_,4>();
+	vd2.ghost_put<add_,1>();
+	vd2.ghost_put<merge_,4>();
 
 	auto p_it3 = vd.getDomainIterator();
 
@@ -717,25 +735,16 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
 	{
 		auto p = p_it3.get();
 
-		ret &= vd.getProp<1>(p) == vd.getProp<0>(p);
+		ret &= vd2.getProp<1>(p) == vd.getProp<0>(p);
 
-		vd.getProp<3>(p).sort();
-		vd.getProp<4>(p).sort();
 
-		ret &= vd.getProp<3>(p).size() == vd.getProp<4>(p).size();
-
-//		if (v_cl.getProcessUnitID() == 0)
-//		{
-//			std::cerr << "Particle: " << p.getKey()  <<  "   Position: " << Point<3,float>(vd.getPos(p)).toString() << std::endl;
+		vd.getProp<3>(p).sort();
+		vd2.getProp<4>(p).sort();
 
-			for (size_t i = 0 ; i < vd.getProp<4>(p).size() ; i++)
-			{
-//				std::cerr << "POSITION: " << vd.getProp<3>(p).get(i).xq.toString() << std::endl;
+		ret &= vd.getProp<3>(p).size() == vd2.getProp<4>(p).size();
 
-//				std::cerr << "ID nn " << vd.getProp<3>(p).get(i).id << "     " << vd.getProp<4>(p).get(i).id << std::endl;
-				ret &= vd.getProp<3>(p).get(i).id == vd.getProp<4>(p).get(i).id;
-			}
-//		}
+		for (size_t i = 0 ; i < vd.getProp<3>(p).size() ; i++)
+			ret &= vd.getProp<3>(p).get(i).id == vd2.getProp<4>(p).get(i).id;
 
 		if (ret == false)
 			break;
@@ -1169,4 +1178,220 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_verlet_list_no_bottom )
 }
 
 
+BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list )
+{
+	Vcluster & v_cl = create_vcluster();
+
+	if (v_cl.getProcessingUnits() > 24)
+		return;
+
+	float L = 1000.0;
+
+    // set the seed
+	// create the random generator engine
+	std::srand(0);
+    std::default_random_engine eg;
+    std::uniform_real_distribution<float> ud(-L,L);
+
+    long int k = 4096 * v_cl.getProcessingUnits();
+
+	long int big_step = k / 4;
+	big_step = (big_step == 0)?1:big_step;
+
+	print_test("Testing 3D periodic vector symmetric cell-list k=",k);
+	BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
+
+	Box<3,float> box({-L,-L,-L},{L,L,L});
+
+	// Boundary conditions
+	size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
+
+	float r_cut = 100.0;
+
+	// ghost
+	Ghost<3,float> ghost(r_cut);
+	Ghost<3,float> ghost2(r_cut);
+	ghost2.setLow(0,0.0);
+	ghost2.setLow(1,0.0);
+	ghost2.setLow(2,0.0);
+
+	// Point and global id
+	struct point_and_gid
+	{
+		size_t id;
+		Point<3,float> xq;
+
+		bool operator<(const struct point_and_gid & pag) const
+		{
+			return (id < pag.id);
+		}
+	};
+
+	typedef  aggregate<size_t,size_t,size_t,openfpm::vector<point_and_gid>,openfpm::vector<point_and_gid>> part_prop;
+
+	// Distributed vector
+	vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
+	vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
+	size_t start = vd.init_size_accum(k);
+
+	auto it = vd.getIterator();
+
+	while (it.isNext())
+	{
+		auto key = it.get();
+
+		vd.getPos(key)[0] = ud(eg);
+		vd.getPos(key)[1] = ud(eg);
+		vd.getPos(key)[2] = ud(eg);
+
+		vd2.getPos(key)[0] = vd.getPos(key)[0];
+		vd2.getPos(key)[1] = vd.getPos(key)[1];
+		vd2.getPos(key)[2] = vd.getPos(key)[2];
+
+		// Fill some properties randomly
+
+		vd.getProp<0>(key) = 0;
+		vd.getProp<1>(key) = 0;
+		vd.getProp<2>(key) = key.getKey() + start;
+
+		vd2.getProp<0>(key) = 0;
+		vd2.getProp<1>(key) = 0;
+		vd2.getProp<2>(key) = key.getKey() + start;
+
+		++it;
+	}
+
+	vd.map();
+	vd2.map();
+
+	// sync the ghost
+	vd.ghost_get<0,2>();
+	vd2.ghost_get<0,2>();
+
+	auto NN = vd.getVerlet(r_cut);
+	auto p_it = vd.getDomainIterator();
+
+	while (p_it.isNext())
+	{
+		auto p = p_it.get();
+
+		Point<3,float> xp = vd.getPos(p);
+
+		auto Np = NN.getNNIterator(p.getKey());
+
+		while (Np.isNext())
+		{
+			auto q = Np.get();
+
+			if (p.getKey() == q)
+			{
+				++Np;
+				continue;
+			}
+
+			// repulsive
+
+			Point<3,float> xq = vd.getPos(q);
+			Point<3,float> f = (xp - xq);
+
+			float distance = f.norm();
+
+			// Particle should be inside 2 * r_cut range
+
+			if (distance < r_cut )
+			{
+				vd.getProp<0>(p)++;
+				vd.getProp<3>(p).add();
+				vd.getProp<3>(p).last().xq = xq;
+				vd.getProp<3>(p).last().id = vd.getProp<2>(q);
+			}
+
+			++Np;
+		}
+
+		++p_it;
+	}
+
+	// We now try symmetric Verlet-list Crs scheme
+
+	auto NN2 = vd2.getVerletCrs(r_cut);
+
+	// Because iterating across particles in the CSR scheme require a Cell-list
+	auto p_it2 = vd2.getParticleIteratorCRS(NN2.getInternalCellList());
+
+	while (p_it2.isNext())
+	{
+		auto p = p_it2.get();
+
+		Point<3,float> xp = vd2.getPos(p);
+
+		auto Np = NN2.getNNIterator<NO_CHECK>(p);
+
+		while (Np.isNext())
+		{
+			auto q = Np.get();
+
+			if (p == q)
+			{
+				++Np;
+				continue;
+			}
+
+			// repulsive
+
+			Point<3,float> xq = vd2.getPos(q);
+			Point<3,float> f = (xp - xq);
+
+			float distance = f.norm();
+
+			if (distance < r_cut )
+			{
+				vd2.getProp<1>(p)++;
+				vd2.getProp<1>(q)++;
+
+				vd2.getProp<4>(p).add();
+				vd2.getProp<4>(q).add();
+
+				vd2.getProp<4>(p).last().xq = xq;
+				vd2.getProp<4>(q).last().xq = xp;
+				vd2.getProp<4>(p).last().id = vd2.getProp<2>(q);
+				vd2.getProp<4>(q).last().id = vd2.getProp<2>(p);
+			}
+
+			++Np;
+		}
+
+		++p_it2;
+	}
+
+	vd2.ghost_put<add_,1>();
+	vd2.ghost_put<merge_,4>();
+
+	auto p_it3 = vd.getDomainIterator();
+
+	bool ret = true;
+	while (p_it3.isNext())
+	{
+		auto p = p_it3.get();
+
+		ret &= vd2.getProp<1>(p) == vd.getProp<0>(p);
+
+
+		vd.getProp<3>(p).sort();
+		vd2.getProp<4>(p).sort();
+
+		ret &= vd.getProp<3>(p).size() == vd2.getProp<4>(p).size();
+
+		for (size_t i = 0 ; i < vd.getProp<3>(p).size() ; i++)
+			ret &= vd.getProp<3>(p).get(i).id == vd2.getProp<4>(p).get(i).id;
+
+		if (ret == false)
+			break;
+
+		++p_it3;
+	}
+
+	BOOST_REQUIRE_EQUAL(ret,true);
+}
+
 #endif /* SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_ */