From 10bc18545990f669e2a9f268a6895b6cd54a57d4 Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Wed, 2 Sep 2015 17:11:17 +0200
Subject: [PATCH] Last changes to staggered

---
 configure.ac                          |   2 +-
 openfpm_data                          |   2 +-
 openfpm_devices                       |   2 +-
 openfpm_io                            |   2 +-
 src/Grid/grid_dist_id.hpp             |  43 +++---
 src/Grid/staggered_dist_grid.hpp      |  16 ++-
 src/Grid/staggered_dist_grid_util.hpp | 198 ++++++++++++++++++++++----
 7 files changed, 210 insertions(+), 55 deletions(-)

diff --git a/configure.ac b/configure.ac
index 437558e10..959aac51e 100755
--- a/configure.ac
+++ b/configure.ac
@@ -89,7 +89,7 @@ IMMDX_LIB_METIS([],[echo "Cannot detect metis, use the --with-metis option if it
 
 ####### include OpenFPM_devices include path
 
-INCLUDES_PATH+="-I. -Isrc/config/ -I../openfpm_io/src -I../openfpm_data/src -I../openfpm_devices/src -I../openfpm_vcluster/src/"
+INCLUDES_PATH+="-I. -Iconfig/ -I../openfpm_io/src -I../openfpm_data/src -I../openfpm_devices/src -I../openfpm_vcluster/src/"
 
 ##### CHECK FOR BOOST ##############
 
diff --git a/openfpm_data b/openfpm_data
index 0f8108a0e..1f7f0323f 160000
--- a/openfpm_data
+++ b/openfpm_data
@@ -1 +1 @@
-Subproject commit 0f8108a0eba32e0249341040a5e127c3f5a7047e
+Subproject commit 1f7f0323f91dada2b98e532ede00ebe3a79de04a
diff --git a/openfpm_devices b/openfpm_devices
index 5e7723822..5fcf26ecf 160000
--- a/openfpm_devices
+++ b/openfpm_devices
@@ -1 +1 @@
-Subproject commit 5e77238220a0ad397afc8939c85b402c09d8e87b
+Subproject commit 5fcf26ecfb5cedb720c6239cca235e14e422aa5c
diff --git a/openfpm_io b/openfpm_io
index d3a6ccf23..a94658c3e 160000
--- a/openfpm_io
+++ b/openfpm_io
@@ -1 +1 @@
-Subproject commit d3a6ccf23ab183d35d77317aba70193ac0ca0bc7
+Subproject commit a94658c3e4fc0f68fd261e7df39cd2a353bd4682
diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index 3931d5880..a1c49613c 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -417,27 +417,6 @@ class grid_dist_id
 
 protected:
 
-	/*! \brief Get the i sub-domain grid
-	 *
-	 * \param i sub-domain
-	 *
-	 * \return local grid
-	 *
-	 */
-	device_grid & get_loc_grid(size_t i)
-	{
-		return loc_grid.get(i);
-	}
-
-	/*! \brief Return the number of local grid
-	 *
-	 * \return the number of local grid
-	 *
-	 */
-	size_t getN_loc_grid()
-	{
-		return loc_grid.size();
-	}
 
 	/*! \brief Get the point where it start the origin of the grid in the sub-domain i
 	 *
@@ -991,6 +970,28 @@ public:
 
 		return true;
 	}
+
+	/*! \brief Get the i sub-domain grid
+	 *
+	 * \param i sub-domain
+	 *
+	 * \return local grid
+	 *
+	 */
+	device_grid & get_loc_grid(size_t i)
+	{
+		return loc_grid.get(i);
+	}
+
+	/*! \brief Return the number of local grid
+	 *
+	 * \return the number of local grid
+	 *
+	 */
+	size_t getN_loc_grid()
+	{
+		return loc_grid.size();
+	}
 };
 
 
diff --git a/src/Grid/staggered_dist_grid.hpp b/src/Grid/staggered_dist_grid.hpp
index ad3f68556..c216231d6 100644
--- a/src/Grid/staggered_dist_grid.hpp
+++ b/src/Grid/staggered_dist_grid.hpp
@@ -79,8 +79,8 @@ public:
 	template<unsigned int p> void setStagPosition(openfpm::vector<comb<dim>> & cmb)
 	{
 #ifdef SE_CLASS1
-		if (mul_extends< boost::mpl::at<ele::type>::type >::ext() != cmb.size())
-			std::cerr << __FILE__ << ":" << __LINE << " error properties has " << mul_extends< boost::mpl::at<ele::type>::type >::ext() << " components, but " << cmb.size() << "has been defined \n";
+		if (extends< typename boost::mpl::at<typename T::type,boost::mpl::int_<p> >::type >::mul() != cmb.size())
+			std::cerr << __FILE__ << ":" << __LINE__ << " error properties has " << extends< typename boost::mpl::at<typename T::type,boost::mpl::int_<p> >::type >::mul() << " components, but " << cmb.size() << "has been defined \n";
 #endif
 		c_prp.get(p) = cmb;
 	}
@@ -113,6 +113,18 @@ public:
 		grid_dist_id<dim,St,T,Decomposition,Memory,device_grid>::write(str,c_prp,spacing);*/
 	}
 
+	/*! \brief Return if the properties is a staggered property or not
+	 *
+	 * \param prp property to check
+	 *
+	 * \return true if the property is staggered
+	 *
+	 */
+	bool is_staggered_prop(size_t prp)
+	{
+		return c_prp[prp].size() != 0;
+	}
+
 	friend class stag_create_and_add_grid<dim,staggered_grid_dist<dim,St,T,Decomposition,Memory,device_grid>,St>;
 };
 
diff --git a/src/Grid/staggered_dist_grid_util.hpp b/src/Grid/staggered_dist_grid_util.hpp
index ee1030827..9ea0ee1c1 100644
--- a/src/Grid/staggered_dist_grid_util.hpp
+++ b/src/Grid/staggered_dist_grid_util.hpp
@@ -10,6 +10,7 @@
 
 #include "util/common.hpp"
 #include "VTKWriter.hpp"
+#include "util/convert.hpp"
 
 /*! \brief Classes to get the number of components of the properties
  *
@@ -178,6 +179,148 @@ struct extends<T[N1][N2][N3][N4][N5][N6][N7][N8][N9][N10]>
 	}
 };
 
+///////////////////// Copy grid extends
+
+/*! \brief Classes to copy each component into a grid and add to the VTKWriter the grid
+ *
+ * \param T property to write
+ * \param dim dimansionality
+ * \param St type of space
+ * \param VTKW VTK writer
+ * \param
+ *
+ */
+template<typename T>
+struct write_stag
+{
+	/*! \brieg write the staggered grid
+	 *
+	 * \tparam p_val property we are going to write
+	 * \tparam sg staggered grid type
+	 * \tparam v_g vector of grids
+	 *
+	 * \param st_g staggered grid
+	 * \param v_g vector of grids
+	 * \param i local grid of the staggered grid we are writing
+	 *
+	 */
+	template<unsigned int p_val, typename sg, typename v_g> static inline void write(sg & st_g, v_g & vg,size_t lg)
+	{
+		// Add a grid;
+		vg.add();
+		size_t k = vg.size() - 1;
+
+		// Get the source and destination grid
+		auto & g_src = st_g.get_loc_grid(lg);
+		auto & g_dst = vg.get(k);
+
+		// Set dimensions and memory
+		g_dst.template resize<HeapMemory>(g_src.getGrid().getSize());
+
+		// copy
+
+		auto it = vg.get(k).getIterator();
+
+		while(it.isNext())
+		{
+			g_dst.template get<0>(it.get()) = g_src.template get<p_val>(it.get());
+
+			++it;
+		}
+	}
+};
+
+/*! \brief for each component add a grid fill it, and add to the VTK writer
+ *
+ * \param T Property to copy
+ * \param N1 number of components
+ *
+ */
+template<typename T,size_t N1>
+struct write_stag<T[N1]>
+{
+	/*! \brieg write the staggered grid
+	 *
+	 * \tparam p_val property we are going to write
+	 * \tparam sg staggered grid type
+	 * \tparam v_g vector of grids
+	 *
+	 * \param st_g staggered grid
+	 * \param v_g vector of grids
+	 * \param i local grid of the staggered grid we are writing
+	 *
+	 */
+	template<unsigned int p_val, typename sg, typename v_g> static inline void write(sg & st_g, v_g & vg,size_t lg)
+	{
+		for (size_t i = 0 ; i < N1 ; i++)
+		{
+			// Add a grid;
+			vg.add();
+			size_t k = vg.size() - 1;
+
+			// Get the source and destination grid
+			auto & g_src = st_g.get_loc_grid(lg);
+			auto & g_dst = vg.get(k);
+
+			// Set dimensions and memory
+			g_dst.template resize<HeapMemory>(g_src.getGrid().getSize());
+
+			auto it = vg.get(k).getIterator();
+
+			while(it.isNext())
+			{
+				g_dst.template get<0>(it.get()) = g_src.template get<p_val>(it.get())[i];
+
+				++it;
+			}
+		}
+	}
+};
+
+//! Partial specialization for N=2 2D-Array
+template<typename T,size_t N1,size_t N2>
+struct write_stag<T[N1][N2]>
+{
+	/*! \brieg write the staggered grid
+	 *
+	 * \tparam p_val property we are going to write
+	 * \tparam sg staggered grid type
+	 * \tparam v_g vector of grids
+	 *
+	 * \param st_g staggered grid
+	 * \param v_g vector of grids
+	 * \param i local grid of the staggered grid we are writing
+	 *
+	 */
+	template<unsigned int p_val, typename sg, typename v_g> static inline void write(sg & st_g, v_g & vg,size_t lg)
+	{
+		for (size_t i = 0 ; i < N1 ; i++)
+		{
+			for (size_t j = 0 ; j < N2 ; j++)
+			{
+				// Add a grid;
+				vg.add();
+				size_t k = vg.size() - 1;
+
+				// Set dimensions and memory
+				vg.get(k).template resize<HeapMemory>(st_g.get_loc_grid(lg).getGrid().getSize());
+
+				// copy
+				auto & g_src = st_g.get_loc_grid(lg);
+				auto & g_dst = vg.get(k);
+				auto it = vg.get(k).getIterator();
+
+				while(it.isNext())
+				{
+					g_dst.template get<0>(it.get()) = g_src.template get<p_val>(it.get())[i][j];
+
+					++it;
+				}
+			}
+		}
+	}
+};
+
 ///////////////////// Staggered default positioning ////////////////////////
 
 /*! \brief this class is a functor for "for_each" algorithm
@@ -391,17 +534,14 @@ public:
 			// Set dimansions and memory
 			vg.get(i).template resize<HeapMemory>(st_g.get_loc_grid(i).getGrid().getSize());
 
-			// create the Memory
-			vg.get(i).template setMemory<HeapMemory>();
-
-			auto g_src = st_g.get_loc_grid(i);
-			auto g_dst = vg.get(i);
+			auto & g_src = st_g.get_loc_grid(i);
+			auto & g_dst = vg.get(i);
 
 			auto it = vg.get(i).getIterator();
 
 			while(it.isNext())
 			{
-				object_si_d< decltype(g_src.get_o(it.get())),decltype(g_dst.get_o(it.get())) ,ENCAP,T::value>(g_src.get_o(it.get()),g_dst.get_o(it.get()));
+				object_si_d< decltype(g_src.get_o(it.get())),decltype(g_dst.get_o(it.get())) ,ENCAP,p_val>(g_src.get_o(it.get()),g_dst.get_o(it.get()));
 
 				++it;
 			}
@@ -413,7 +553,7 @@ public:
 			vtk_w.add(g_dst,offset,spacing,dom);
 		}
 
-		vtk_w.write("vtk_grids_st_" + std::to_string(T::value) + ".vtk");
+		vtk_w.write("vtk_grids_st_" + std::to_string(p_val) + ".vtk");
 	}
 
 	template<unsigned int p_val> void out_staggered()
@@ -421,44 +561,46 @@ public:
 		// property type
 		typedef typename boost::mpl::at< typename st_grid::value_type::type , typename boost::mpl::int_<p_val> >::type ele;
 
+		// Eliminate the extends
+		typedef typename std::remove_all_extents<ele>::type r_ele;
+
 		// create an openfpm format object from the property type
-		typedef object<typename boost::fusion::vector<ele>> d_object;
+		typedef object<typename boost::fusion::vector<r_ele>> d_object;
 
 		VTKWriter<boost::mpl::pair<grid_cpu<dim, d_object >,St>,VECTOR_GRIDS> vtk_w;
 
 		// Create a vector of grids
+		openfpm::vector< grid_cpu<dim, d_object > > vg;
 
-		openfpm::vector< grid_cpu<dim, d_object > > vg(st_g.getN_loc_grid());
+		size_t k = 0;
 
 		// for each domain grid
-		for (size_t i = 0 ; i < vg.size() ; i++)
+		for (size_t i = 0 ; i < st_g.getN_loc_grid() ; i++)
 		{
-			// Set dimansions and memory
-			vg.get(i).template resize<HeapMemory>(st_g.get_loc_grid(i).getGrid().getSize());
+			write_stag<ele>::template write<p_val, st_grid,openfpm::vector< grid_cpu<dim, d_object > > >(st_g,vg,i);
 
-			// create the Memory
-			vg.get(i).template setMemory<HeapMemory>();
-
-			auto g_src = st_g.get_loc_grid(i);
-			auto g_dst = vg.get(i);
+			// for each component
+			for ( ; k < vg.size() ; k++)
+			{
+				Point<dim,St> offset = st_g.getOffset(i);
+				Point<dim,St> spacing = st_g.getSpacing();
+				Box<dim,size_t> dom = st_g.getDomain(i);
 
-			auto it = vg.get(i).getIterator();
+				// Adjust for staggered
 
-			while(it.isNext())
-			{
-				object_si_d< decltype(g_src.get_o(it.get())),decltype(g_dst.get_o(it.get())) ,ENCAP,T::value>(g_src.get_o(it.get()),g_dst.get_o(it.get()));
+				Point<dim,St> middle = spacing / 2;
+				Point<dim,St> one;
+				one.one();
+				one = one + toPoint<dim,St>::convert(st_g.c_prp[p_val].get(k));
+				offset = offset + middle * one;
 
-				++it;
+				vtk_w.add(vg.get(k),offset,spacing,dom);
 			}
 
-			Point<dim,St> offset = st_g.getOffset(i);
-			Point<dim,St> spacing = st_g.getSpacing();
-			Box<dim,size_t> dom = st_g.getDomain(i);
-
-			vtk_w.add(g_dst,offset,spacing,dom);
+			k = vg.size();
 		}
 
-		vtk_w.write("vtk_grids_st_" + std::to_string(T::value) + ".vtk");
+		vtk_w.write("vtk_grids_st_" + std::to_string(p_val) + ".vtk");
 	}
 
 	//! It call the copy function for each property
-- 
GitLab