diff --git a/src/FiniteDifference/FDScheme.hpp b/src/FiniteDifference/FDScheme.hpp
index b2e55433876fd5890357de1812bfc9524128bd68..00cac997777bd5d57efcfddb1e3986cf34638caf 100644
--- a/src/FiniteDifference/FDScheme.hpp
+++ b/src/FiniteDifference/FDScheme.hpp
@@ -134,6 +134,38 @@ public:
 
 private:
 
+	// Encapsulation of the b term as constant
+	struct constant_b
+	{
+		typename Sys_eqs::stype scal;
+
+		constant_b(typename Sys_eqs::stype scal)
+		{
+			this->scal = scal;
+		}
+
+		typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
+		{
+			return scal;
+		}
+	};
+
+	// Encapsulation of the b term as grid
+	template<typename grid, unsigned int prp>
+	struct grid_b
+	{
+		grid & gr;
+
+		grid_b(grid & gr)
+		:gr(gr)
+		{}
+
+		typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
+		{
+			return gr.template get<prp>(key);
+		}
+	};
+
 	//! Padding
 	Padding<Sys_eqs::dims> pd;
 
@@ -247,34 +279,36 @@ private:
 		nz_rows.resize(row_b);
 
 		for (size_t i = 0 ; i < trpl.size() ; i++)
-		{
-			nz_rows.get(trpl.get(i).row()) = true;
-		}
+			nz_rows.get(trpl.get(i).row() - s_pnt*Sys_eqs::nvar) = true;
 
 		// Indicate all the non zero colums
-		openfpm::vector<unsigned> nz_cols;
-		nz_cols.resize(row_b);
+		// This check can be done only on single processor
 
-		for (size_t i = 0 ; i < trpl.size() ; i++)
+		Vcluster & v_cl = create_vcluster();
+		if (v_cl.getProcessingUnits() == 1)
 		{
-			nz_cols.get(trpl.get(i).col()) = true;
-		}
+			openfpm::vector<unsigned> nz_cols;
+			nz_cols.resize(row_b);
 
-		// all the rows must have a non zero element
-		for (size_t i = 0 ; i < nz_rows.size() ; i++)
-		{
-			if (nz_rows.get(i) == false)
+			for (size_t i = 0 ; i < trpl.size() ; i++)
+				nz_cols.get(trpl.get(i).col()) = true;
+
+			// all the rows must have a non zero element
+			for (size_t i = 0 ; i < nz_rows.size() ; i++)
 			{
-				key_and_eq ke = from_row_to_key(i);
-				std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i <<  " is not filled, position " << ke.key.to_string() << " equation: " << ke.eq << "\n";
+				if (nz_rows.get(i) == false)
+				{
+					key_and_eq ke = from_row_to_key(i);
+					std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i <<  " is not filled, position " << ke.key.to_string() << " equation: " << ke.eq << "\n";
+				}
 			}
-		}
 
-		// all the colums must have a non zero element
-		for (size_t i = 0 ; i < nz_cols.size() ; i++)
-		{
-			if (nz_cols.get(i) == false)
-				std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix colum " << i << " is not filled\n";
+			// all the colums must have a non zero element
+			for (size_t i = 0 ; i < nz_cols.size() ; i++)
+			{
+				if (nz_cols.get(i) == false)
+					std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix colum " << i << " is not filled\n";
+			}
 		}
 	}
 
@@ -328,6 +362,178 @@ private:
 		}
 	}
 
+	/*! \brief Copy a given solution vector in a normal grid
+	 *
+	 * \tparam Vct Vector type
+	 * \tparam Grid_dst target grid
+	 * \tparam pos set of property
+	 *
+	 * \param v Vector
+	 * \param g_dst target normal grid
+	 *
+	 */
+	template<typename Vct, typename Grid_dst ,unsigned int ... pos> void copy_normal(Vct & v, Grid_dst & g_dst)
+	{
+		// check that g_dst is staggered
+		if (g_dst.is_staggered() == true)
+			std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be normal " << std::endl;
+
+#ifdef SE_CLASS1
+
+		if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize())
+			std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid in size does not match the mapping grid" << std::endl;
+#endif
+
+		// sub-grid iterator over the grid map
+		auto g_map_it = g_map.getDomainIterator();
+
+		// Iterator over the destination grid
+		auto g_dst_it = g_dst.getDomainIterator();
+
+		while (g_map_it.isNext() == true)
+		{
+			typedef typename to_boost_vmpl<pos...>::type vid;
+			typedef boost::mpl::size<vid> v_size;
+
+			auto key_src = g_map_it.get();
+			size_t lin_id = g_map.template get<0>(key_src);
+
+			// destination point
+			auto key_dst = g_dst_it.get();
+
+			// Transform this id into an id for the vector
+
+			copy_ele<Sys_eqs_typ, Grid_dst,Vct> cp(key_dst,g_dst,v,lin_id,g_map.size());
+
+			boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
+
+			++g_map_it;
+			++g_dst_it;
+		}
+	}
+
+	/*! \brief Impose an operator
+	 *
+	 * This function impose an operator on a particular grid region to produce the system
+	 *
+	 * Ax = b
+	 *
+	 * ## Stokes equation 2D, lid driven cavity with one splipping wall
+	 * \snippet eq_unit_test.hpp Copy the solution to grid
+	 *
+	 * \param op Operator to impose (A term)
+	 * \param num right hand side of the term (b term)
+	 * \param id Equation id in the system that we are imposing
+	 * \param it_d iterator that define where you want to impose
+	 *
+	 */
+	template<typename T, typename bop, typename iterator> void impose(const T & op ,
+			                         bop num,
+									 long int id ,
+									 const iterator & it_d)
+	{
+		openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
+
+		auto it = it_d;
+		grid_sm<Sys_eqs::dims,void> gs = g_map.getGridInfoVoid();
+
+		std::unordered_map<long int,float> cols;
+
+		// iterate all the grid points
+		while (it.isNext())
+		{
+			// get the position
+			auto key = it.get();
+
+			// Calculate the non-zero colums
+			T::value(g_map,key,gs,spacing,cols,1.0);
+
+			// indicate if the diagonal has been set
+			bool is_diag = false;
+
+			// create the triplet
+			for ( auto it = cols.begin(); it != cols.end(); ++it )
+			{
+				trpl.add();
+				trpl.last().row() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
+				trpl.last().col() = it->first;
+				trpl.last().value() = it->second;
+
+				if (trpl.last().row() == trpl.last().col())
+					is_diag = true;
+
+//				std::cout << "(" << trpl.last().row() << "," << trpl.last().col() << "," << trpl.last().value() << ")" << "\n";
+			}
+
+			// If does not have a diagonal entry put it to zero
+			if (is_diag == false)
+			{
+				trpl.add();
+				trpl.last().row() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
+				trpl.last().col() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
+				trpl.last().value() = 0.0;
+			}
+
+			b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key);
+
+			cols.clear();
+//			std::cout << "\n";
+
+			// if SE_CLASS1 is defined check the position
+#ifdef SE_CLASS1
+//			T::position(key,gs,s_pos);
+#endif
+
+			++row;
+			++row_b;
+			++it;
+		}
+	}
+
+	/*! \brief Construct the gmap structure
+	 *
+	 */
+	void construct_gmap()
+	{
+		Vcluster & v_cl = create_vcluster();
+
+		// Calculate the size of the local domain
+		size_t sz = g_map.getLocalDomainSize();
+
+		// Get the total size of the local grids on each processors
+		v_cl.allGather(sz,pnt);
+		v_cl.execute();
+		s_pnt = 0;
+
+		// calculate the starting point for this processor
+		for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
+			s_pnt += pnt.get(i);
+
+		// resize b if needed
+		b.resize(Sys_eqs::nvar * g_map.size(),Sys_eqs::nvar * sz);
+
+		// Calculate the starting point
+
+		// Counter
+		size_t cnt = 0;
+
+		// Create the re-mapping grid
+		auto it = g_map.getDomainIterator();
+
+		while (it.isNext())
+		{
+			auto key = it.get();
+
+			g_map.template get<0>(key) = cnt + s_pnt;
+
+			++cnt;
+			++it;
+		}
+
+		// sync the ghost
+		g_map.template ghost_get<0>();
+	}
+
 public:
 
 	/*! \brief set the staggered position for each property
@@ -382,12 +588,14 @@ public:
 	}
 
 	/*! \brief Constructor
+	 *
+	 * The periodicity is given by the grid b_g
 	 *
 	 * \param pd Padding, how many points out of boundary are present
-	 * \param stencil how many ghost points are required for this calculation
+	 * \param stencil maximum extension of the stencil on each directions
 	 * \param domain the domain
 	 * \param gs grid infos where Finite differences work
-	 * \param b_g maximum extension of the stencil on each directions
+	 * \param b_g Finite difference grid (it is not important what it contain only its decomposition is used)
 	 *
 	 */
 	FDScheme(Padding<Sys_eqs::dims> & pd,
@@ -397,49 +605,18 @@ public:
 			 const typename Sys_eqs::b_grid & b_g)
 	:pd(pd),gs(gs),g_map(b_g,stencil,pd),row(0),row_b(0)
 	{
-		Vcluster & v_cl = b_g.getDecomposition().getVC();
-
-		// Calculate the size of the local domain
-		size_t sz = g_map.getLocalDomainSize();
-
-		// Get the total size of the local grids on each processors
-		v_cl.allGather(sz,pnt);
-		v_cl.execute();
-		s_pnt = 0;
-
-		// calculate the starting point for this processor
-		for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
-			s_pnt += pnt.get(i);
-
-		// resize b if needed
-		b.resize(Sys_eqs::nvar * g_map.size(),Sys_eqs::nvar * sz);
-
-		// Calculate the starting point
-
-		// Counter
-		size_t cnt = 0;
-
-		// Create the re-mapping grid
-		auto it = g_map.getDomainIterator();
-
-		while (it.isNext())
-		{
-			auto key = it.get();
-
-			g_map.template get<0>(key) = cnt + s_pnt;
-
-			++cnt;
-			++it;
-		}
-
-		// sync the ghost
-		g_map.template ghost_get<0>();
+		construct_gmap();
 
 		// Create a CellDecomposer and calculate the spacing
 
 		size_t sz_g[Sys_eqs::dims];
 		for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
-			sz_g[i] = gs.getSize()[i] - 1;
+		{
+			if (Sys_eqs::boundary[i] == NON_PERIODIC)
+				sz_g[i] = gs.getSize()[i] - 1;
+			else
+				sz_g[i] = gs.getSize()[i];
+		}
 
 		CellDecomposer_sm<Sys_eqs::dims,typename Sys_eqs::stype> cd(domain,sz_g,0);
 
@@ -495,7 +672,9 @@ public:
         if (increment == true)
                 ++it;
 
-        impose(op,num,id,it);
+        constant_b b(num);
+
+        impose(op,b,id,it);
 
 	}
 
@@ -514,64 +693,39 @@ public:
 	 * \param it_d iterator that define where you want to impose
 	 *
 	 */
-	template<typename T> void impose(const T & op , typename Sys_eqs::stype num ,long int id ,grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d)
+	template<typename T> void impose(const T & op ,
+									 typename Sys_eqs::stype num,
+									 long int id ,
+									 grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d)
 	{
-		openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
-
-		auto it = it_d;
-		grid_sm<Sys_eqs::dims,void> gs = g_map.getGridInfoVoid();
-
-		std::unordered_map<long int,float> cols;
-
-		// iterate all the grid points
-		while (it.isNext())
-		{
-			// get the position
-			auto key = it.get();
-
-			// Calculate the non-zero colums
-			T::value(g_map,key,gs,spacing,cols,1.0);
-
-			// indicate if the diagonal has been set
-			bool is_diag = false;
-
-			// create the triplet
-			for ( auto it = cols.begin(); it != cols.end(); ++it )
-			{
-				trpl.add();
-				trpl.last().row() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
-				trpl.last().col() = it->first;
-				trpl.last().value() = it->second;
-
-				if (trpl.last().row() == trpl.last().col())
-					is_diag = true;
-
-//				std::cout << "(" << trpl.last().row() << "," << trpl.last().col() << "," << trpl.last().value() << ")" << "\n";
-			}
-
-			// If does not have a diagonal entry put it to zero
-			if (is_diag == false)
-			{
-				trpl.add();
-				trpl.last().row() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
-				trpl.last().col() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
-				trpl.last().value() = 0.0;
-			}
-
-			b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num;
+		constant_b b(num);
 
-			cols.clear();
-//			std::cout << "\n";
+		impose(op,b,id,it_d);
+	}
 
-			// if SE_CLASS1 is defined check the position
-#ifdef SE_CLASS1
-//			T::position(key,gs,s_pos);
-#endif
+	/*! \brief Impose an operator
+	 *
+	 * This function impose an operator on a particular grid region to produce the system
+	 *
+	 * Ax = b
+	 *
+	 * ## Stokes equation 2D, lid driven cavity with one splipping wall
+	 * \snippet eq_unit_test.hpp Copy the solution to grid
+	 *
+	 * \param op Operator to impose (A term)
+	 * \param num right hand side of the term (b term)
+	 * \param id Equation id in the system that we are imposing
+	 * \param it_d iterator that define where you want to impose
+	 *
+	 */
+	template<unsigned int prp, typename T, typename b_term, typename iterator> void impose(const T & op ,
+									 b_term & b_t,
+									 long int id ,
+									 const iterator & it_d)
+	{
+		grid_b<b_term,prp> b(b_t);
 
-			++row;
-			++row_b;
-			++it;
-		}
+		impose(op,b,id,it_d);
 	}
 
 	//! type of the sparse matrix
@@ -587,7 +741,9 @@ public:
 #ifdef SE_CLASS1
 		consistency();
 #endif
-		A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar,g_map.getLocalDomainSize()*Sys_eqs::nvar,g_map.getLocalDomainSize()*Sys_eqs::nvar);
+		A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar,
+				 g_map.getLocalDomainSize()*Sys_eqs::nvar,
+				 g_map.getLocalDomainSize()*Sys_eqs::nvar);
 
 		return A;
 
@@ -632,7 +788,17 @@ public:
 			{
 				// Create a temporal staggered grid and copy the data there
 				auto & g_map = this->getMap();
-				staggered_grid_dist<Grid_dst::dims,typename Grid_dst::stype,typename Grid_dst::value_type,typename Grid_dst::decomposition::extended_type, typename Grid_dst::memory_type, typename Grid_dst::device_grid_type> stg(g_dst,g_map.getDecomposition().getGhost(),this->getPadding());
+
+				// Convert the ghost in grid units
+
+				Ghost<Grid_dst::dims,long int> g_int;
+				for (size_t i = 0 ; i < Grid_dst::dims ; i++)
+				{
+					g_int.setLow(i,g_map.getDecomposition().getGhost().getLow(i) / g_map.spacing(i));
+					g_int.setHigh(i,g_map.getDecomposition().getGhost().getHigh(i) / g_map.spacing(i));
+				}
+
+				staggered_grid_dist<Grid_dst::dims,typename Grid_dst::stype,typename Grid_dst::value_type,typename Grid_dst::decomposition::extended_type, typename Grid_dst::memory_type, typename Grid_dst::device_grid_type> stg(g_dst,g_int,this->getPadding());
 				stg.setDefaultStagPosition();
 				copy_staggered<Vct,decltype(stg),pos...>(v,stg);
 
@@ -641,6 +807,10 @@ public:
 				stg.template to_normal<Grid_dst,pos...>(g_dst,this->getPadding(),start,stop);
 			}
 		}
+		else
+		{
+			copy_normal<Vct,Grid_dst,pos...>(v,g_dst);
+		}
 	}
 };
 
diff --git a/src/Makefile.am b/src/Makefile.am
index d802738e4a88986d8fed6e1501633cc39a4ccaae..bb2f3e1442f77bbb79de0a7160310502071c7b40 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,8 @@ Solvers/umfpack_solver.hpp Solvers/petsc_solver.hpp \
 util/petsc_util.hpp util/linalgebra_lib.hpp util/util_num.hpp util/grid_dist_testing.hpp  \
 FiniteDifference/Average.hpp FiniteDifference/Derivative.hpp FiniteDifference/eq.hpp FiniteDifference/FDScheme.hpp FiniteDifference/Laplacian.hpp FiniteDifference/mul.hpp FiniteDifference/sum.hpp FiniteDifference/util/common.hpp \
 PSE/Kernels.hpp PSE/Kernels_test_util.hpp Operators/Vector/vector_dist_operators_extensions.hpp Operators/Vector/vector_dist_operators.hpp Operators/Vector/vector_dist_operators_apply_kernel.hpp Operators/Vector/vector_dist_operators_functions.hpp Operators/Vector/vector_dist_operator_assign.hpp \
-Draw/DrawParticles.hpp Draw/PointIterator.hpp Draw/PointIteratorSkin.hpp
+Draw/DrawParticles.hpp Draw/PointIterator.hpp Draw/PointIteratorSkin.hpp \
+interpolation/interpolation.hpp interpolation/mp4_kernel.hpp interpolation/z_spline.hpp
 
 .cu.o :
 	$(NVCC) $(NVCCFLAGS) -o $@ -c $<
diff --git a/src/Matrix/SparseMatrix_petsc.hpp b/src/Matrix/SparseMatrix_petsc.hpp
index 78d352d1ab1d7d4a3921231173b26324edec3724..b9c2191407d21e12ec98456b8793235aa763ecd1 100644
--- a/src/Matrix/SparseMatrix_petsc.hpp
+++ b/src/Matrix/SparseMatrix_petsc.hpp
@@ -103,31 +103,36 @@ public:
 
 private:
 
-	// Size of the matrix
+	//! Number of matrix row (global)
 	size_t g_row;
+	//! Number of matrix colums (global)
 	size_t g_col;
 
-	// Local size of the matrix
+	//! Number of matrix row (local)
 	size_t l_row;
+	//! Number of matrix colums (local)
 	size_t l_col;
 
-	// starting row for this processor
+	//! starting row for this processor
 	size_t start_row;
 
-	// indicate if the matrix has been created
+	//! indicate if the matrix has been created
 	bool m_created = false;
 
-	// PETSC Matrix
+	//! PETSC Matrix
 	Mat mat;
+
+	//! Triplets of the matrix
 	openfpm::vector<triplet_type> trpl;
-	openfpm::vector<triplet_type> trpl_recv;
 
-	// temporary list of values
+
+	//! temporary list of values
 	mutable openfpm::vector<PetscScalar> vals;
-	// temporary list of colums
+	//! temporary list of colums
 	mutable openfpm::vector<PetscInt> cols;
-	// PETSC d_nnz and o_nnz
+	//! PETSC d_nnz
 	mutable openfpm::vector<PetscInt> d_nnz;
+	//! PETSC o_nnz
 	mutable openfpm::vector<PetscInt> o_nnz;
 
 	/*! \brief Fill the petsc Matrix
@@ -152,7 +157,7 @@ private:
 		{
 			PetscInt row = trpl.get(i).row();
 
-			while(row == trpl.get(i).row() && i < trpl.size())
+			while(i < trpl.size() && row == trpl.get(i).row())
 			{
 				if ((size_t)trpl.get(i).col() >= start_row && (size_t)trpl.get(i).col() < start_row + l_row)
 					d_nnz.get(row - start_row)++;
@@ -176,7 +181,7 @@ private:
 
 			PetscInt row = trpl.get(i).row();
 
-			while(row == trpl.get(i).row() && i < trpl.size())
+			while(i < trpl.size() && row == trpl.get(i).row())
 			{
 				vals.add(trpl.get(i).value());
 				cols.add(trpl.get(i).col());
@@ -237,7 +242,7 @@ public:
 		{PETSC_SAFE_CALL(MatDestroy(&mat));}
 	}
 
-	/*! \brief Get the Matrix triplets bugger
+	/*! \brief Get the Matrix triplets buffer
 	 *
 	 * It return a buffer that can be filled with triplets
 	 *
diff --git a/src/Solvers/petsc_solver.hpp b/src/Solvers/petsc_solver.hpp
index d7ec9a30db39d9728c1d55402271cf01315e1b9d..795e0f34cf8f603d38b4353f1d257a54a7dfa60f 100644
--- a/src/Solvers/petsc_solver.hpp
+++ b/src/Solvers/petsc_solver.hpp
@@ -16,6 +16,8 @@
 #include <petscksp.h>
 #include <petsctime.h>
 #include "Plot/GoogleChart.hpp"
+#include "Matrix/SparseMatrix.hpp"
+#include "Vector/Vector.hpp"
 
 #define UMFPACK_NONE 0
 
diff --git a/src/main.cpp b/src/main.cpp
index 6f3c9131de95cec2a6ff080c2bb25f425ee81bb2..fdb08845570c9f532770a5cf3b80a773ec90cecb 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,3 +16,4 @@
 #include "PSE/Kernels_unit_tests.hpp"
 #include "Operators/Vector/vector_dist_operators_unit_tests.hpp"
 #include "Draw/DrawParticles_unit_tests.hpp"
+#include "interpolation/interpolation_unit_tests.hpp"