From f60b3c188e2c769d4b9f677ac48214296346c00e Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Sun, 18 Oct 2015 20:38:13 +0200
Subject: [PATCH] Adding sub grid iterator

---
 openfpm_data                        |   2 +-
 openfpm_numerics                    |   2 +-
 src/Grid/grid_dist_id.hpp           |  17 +++
 src/Grid/grid_dist_id_unit_test.hpp | 218 +++++++++++++++++++++++++++-
 src/main.cpp                        |   1 -
 5 files changed, 236 insertions(+), 4 deletions(-)

diff --git a/openfpm_data b/openfpm_data
index 2e36a553e..49040a1f7 160000
--- a/openfpm_data
+++ b/openfpm_data
@@ -1 +1 @@
-Subproject commit 2e36a553e379e6712b62abeffce479b005774c91
+Subproject commit 49040a1f74848f700ffda26002d98191b25ea813
diff --git a/openfpm_numerics b/openfpm_numerics
index 0c51112a6..1a6ed2911 160000
--- a/openfpm_numerics
+++ b/openfpm_numerics
@@ -1 +1 @@
-Subproject commit 0c51112a6a0808e7209329de9d4639c1e440a815
+Subproject commit 1a6ed29114ae41e2befcfcfb33ffab58986b6f6b
diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index 5854c6657..f75525113 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -8,6 +8,7 @@
 #include "Space/SpaceBox.hpp"
 #include "util/mathutil.hpp"
 #include "grid_dist_id_iterator.hpp"
+#include "grid_dist_id_iterator_sub.hpp"
 #include "grid_dist_key.hpp"
 #include "NN/CellList/CellDecomposer.hpp"
 #include "util/object_util.hpp"
@@ -39,6 +40,8 @@
  * \snippet grid_dist_id_unit_test.hpp Create and access a distributed grid complex
  * ### Synchronize a distributed grid for complex structures
  * \snippet grid_dist_id_unit_test.hpp Synchronized distributed grid complex
+ * ### Usage of a grid dist iterator sub
+ * \snippet grid_dist_id_unit_test.hpp Usage of a sub_grid iterator
  *
  */
 template<unsigned int dim, typename St, typename T, typename Decomposition,typename Memory=HeapMemory , typename device_grid=grid_cpu<dim,T> >
@@ -538,6 +541,20 @@ public:
 		return it;
 	}
 
+	/*! \brief It return an iterator that span the grid domain only in the specified
+	 * part
+	 *
+	 * \param start point
+	 * \param stop point
+	 *
+	 */
+	grid_dist_iterator_sub<dim,device_grid> getSubDomainIterator(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop)
+	{
+		grid_dist_iterator_sub<dim,device_grid> it(start,stop,loc_grid,gdb_ext);
+
+		return it;
+	}
+
 	//! Destructor
 	~grid_dist_id()
 	{
diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp
index a24d3a082..ca6d7fba0 100644
--- a/src/Grid/grid_dist_id_unit_test.hpp
+++ b/src/Grid/grid_dist_id_unit_test.hpp
@@ -74,6 +74,89 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter_test)
 	}
 }
 
+void Test2D_sub(const Box<2,float> & domain, long int k)
+{
+	long int big_step = k / 30;
+	big_step = (big_step == 0)?1:big_step;
+	long int small_step = 1;
+
+	// this test is only performed when the number of processor is <= 32
+	if (global_v_cluster->getProcessingUnits() > 32)
+		return;
+
+	print_test( "Testing 2D grid sub iterator k<=",k);
+
+	// 2D test
+	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
+	{
+		BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );
+
+		//! [Create and access a distributed grid]
+
+		// grid size
+		size_t sz[2];
+		sz[0] = k;
+		sz[1] = k;
+
+		float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/2.0f);
+
+		// Ghost
+		Ghost<2,float> g(0.01 / factor);
+
+		// Distributed grid with id decomposition
+		grid_dist_id<2, float, scalar<float>, CartDecomposition<2,float>> g_dist(sz,domain,g);
+
+		// check the consistency of the decomposition
+		bool val = g_dist.getDecomposition().check_consistency();
+		BOOST_REQUIRE_EQUAL(val,true);
+
+		// 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;
+		auto dom = g_dist.getSubDomainIterator(one,one_end);
+
+		while (dom.isNext())
+		{
+			auto key = dom.get();
+			auto key_g = g_dist.getGKey(key);
+
+			// key_g should never be 1 or k-1
+			check &= (key_g.get(0) == 0 || key_g.get(0) == k-1)?false:true;
+			check &= (key_g.get(1) == 0 || key_g.get(1) == k-1)?false:true;
+
+			g_dist.template get<0>(key) = info.LinId(key_g);
+
+			// Count the point
+			count++;
+
+			++dom;
+		}
+
+		BOOST_REQUIRE_EQUAL(check,true);
+
+		//! [Usage of a sub_grid iterator]
+
+		// Get the virtual cluster machine
+		Vcluster & vcl = g_dist.getVC();
+
+		// reduce
+		vcl.sum(count);
+		vcl.execute();
+
+		// Check
+		BOOST_REQUIRE_EQUAL(count,(k-2)*(k-2));
+	}
+}
+
 void Test2D(const Box<2,float> & domain, long int k)
 {
 	long int big_step = k / 30;
@@ -179,6 +262,119 @@ void Test2D(const Box<2,float> & domain, long int k)
 	}
 }
 
+void Test3D_sub(const Box<3,float> & domain, long int k)
+{
+	long int big_step = k / 30;
+	big_step = (big_step == 0)?1:big_step;
+	long int small_step = 1;
+
+	// this test is only performed when the number of processor is <= 32
+	if (global_v_cluster->getProcessingUnits() > 32)
+		return;
+
+	print_test( "Testing 3D grid sub k<=",k);
+
+	// 3D test
+	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
+	{
+		BOOST_TEST_CHECKPOINT( "Testing 3D grid sub k=" << k );
+
+		// grid size
+		size_t sz[3];
+		sz[0] = k;
+		sz[1] = k;
+		sz[2] = k;
+
+		// factor
+		float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
+
+		// Ghost
+		Ghost<3,float> g(0.01 / factor);
+
+		// Distributed grid with id decomposition
+		grid_dist_id<3, float, scalar<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);
+
+		// check the consistency of the decomposition
+		bool val = g_dist.getDecomposition().check_consistency();
+		BOOST_REQUIRE_EQUAL(val,true);
+
+		// Grid sm
+		grid_sm<3,void> info(sz);
+
+		// get the domain iterator
+		size_t count = 0;
+
+		auto dom = g_dist.getDomainIterator();
+
+		while (dom.isNext())
+		{
+			auto key = dom.get();
+			auto key_g = g_dist.getGKey(key);
+
+			g_dist.template get<0>(key) = info.LinId(key_g);
+
+			// Count the point
+			count++;
+
+			++dom;
+		}
+
+		// Get the virtual cluster machine
+		Vcluster & vcl = g_dist.getVC();
+
+		// reduce
+		vcl.sum(count);
+		vcl.execute();
+
+		// Check
+		BOOST_REQUIRE_EQUAL(count,k*k*k);
+
+		bool match = true;
+
+		auto dom2 = g_dist.getDomainIterator();
+
+		// check that the grid store the correct information
+		while (dom2.isNext())
+		{
+			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;
+		}
+
+		BOOST_REQUIRE_EQUAL(match,true);
+
+		//! [Synchronize the ghost and check the information]
+
+		g_dist.template ghost_get<0>();
+
+		// check that the communication is correctly completed
+
+		auto domg = g_dist.getDomainGhostIterator();
+
+		// 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);
+
+			// 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;
+			}
+
+			++domg;
+		}
+
+		BOOST_REQUIRE_EQUAL(match,true);
+
+		//! [Synchronize the ghost and check the information]
+	}
+}
+
 void Test3D(const Box<3,float> & domain, long int k)
 {
 	long int big_step = k / 30;
@@ -187,7 +383,7 @@ void Test3D(const Box<3,float> & domain, long int k)
 
 	print_test( "Testing 3D grid k<=",k);
 
-	// 2D test
+	// 3D test
 	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
 	{
 		BOOST_TEST_CHECKPOINT( "Testing 3D grid k=" << k );
@@ -634,6 +830,26 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
 	Test3D_complex(domain3,k);
 }
 
+BOOST_AUTO_TEST_CASE( grid_dist_id_sub_iterator_test_use)
+{
+	// Domain
+	Box<2,float> domain({0.0,0.0},{1.0,1.0});
+
+	// Initialize the global VCluster
+	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
+
+	long int k = 1024*1024*global_v_cluster->getProcessingUnits();
+	k = std::pow(k, 1/2.);
+
+	Test2D_sub(domain,k);
+	// Domain
+	Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
+
+	k = 128*128*128*global_v_cluster->getProcessingUnits();
+	k = std::pow(k, 1/3.);
+	Test3D_sub(domain3,k);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 #endif
diff --git a/src/main.cpp b/src/main.cpp
index fe5923ba5..529be072e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,4 +26,3 @@
 #include "Grid/grid_dist_id_unit_test.hpp"
 #include "Vector/vector_dist_unit_test.hpp"
 
-
-- 
GitLab