From 43252977e27cd744f4737abc9b958ef9c8f10954 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <incardon@mpi-cbg.de> Date: Mon, 19 Oct 2015 20:27:11 +0200 Subject: [PATCH] Changes for numerics --- openfpm_numerics | 2 +- src/Grid/grid_dist_id.hpp | 131 +++++++++++++++++----------- src/Grid/grid_dist_id_unit_test.hpp | 114 ++++++++++++++++-------- 3 files changed, 160 insertions(+), 87 deletions(-) diff --git a/openfpm_numerics b/openfpm_numerics index 1a6ed2911..b4d8373ac 160000 --- a/openfpm_numerics +++ b/openfpm_numerics @@ -1 +1 @@ -Subproject commit 1a6ed29114ae41e2befcfcfb33ffab58986b6f6b +Subproject commit b4d8373acf148fcfb868fc3edff3eb2aed78c881 diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp index f75525113..67b80376e 100644 --- a/src/Grid/grid_dist_id.hpp +++ b/src/Grid/grid_dist_id.hpp @@ -80,6 +80,12 @@ class grid_dist_id // Receiving buffer for particles ghost get openfpm::vector<HeapMemory> recv_mem_gg; + // Grid informations object + grid_sm<dim,T> ginfo; + + // Grid informations object without type + grid_sm<dim,void> ginfo_v; + /*! \brief Call-back to allocate buffer to receive incoming objects (external ghost boxes) * * \param msg_i message size required to receive from i @@ -350,11 +356,63 @@ class grid_dist_id } } + /*! \brief Create the grids on memory + * + */ + void Create() + { + Box<dim,St> g_rnd_box; + for (size_t i = 0 ; i < dim ; i++) {g_rnd_box.setHigh(i,0.5); g_rnd_box.setLow(i,-0.5);} + + // Get the number of local grid needed + size_t n_grid = dec.getNLocalHyperCube(); + + // create local grids for each hyper-cube + loc_grid = v_cl.allocate<device_grid>(n_grid); + + // Size of the grid on each dimension + size_t l_res[dim]; + + // Allocate the grids + for (size_t i = 0 ; i < n_grid ; i++) + { + gdb_ext.add(); + + // Get the local hyper-cube + SpaceBox<dim,St> sp = dec.getLocalHyperCube(i); + SpaceBox<dim,St> sp_g = dec.getSubDomainWithGhost(i); + + // Convert from SpaceBox<dim,St> to SpaceBox<dim,long int> + SpaceBox<dim,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp); + SpaceBox<dim,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g); + + //! Save the origin of the sub-domain of the local grid + gdb_ext.last().origin = sp_tg.getP1(); + + // save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning) + // and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate + gdb_ext.last().Dbox = sp_t; + gdb_ext.last().Dbox -= sp_tg.getP1(); + + // center to zero + sp_tg -= sp_tg.getP1(); + + // Get the size of the local grid + for (size_t i = 0 ; i < dim ; i++) {l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;} + + // Set the dimensions of the local grid + loc_grid.get(i).resize(l_res); + } + } + public: + // Which kind of grid the structure store + typedef device_grid d_grid; + //! constructor grid_dist_id(Vcluster v_cl, Decomposition & dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,T> & ghost) - :domain(domain),ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec) + :domain(domain),ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec),ginfo(g_sz),ginfo_v(g_sz) { check_size(g_sz); @@ -397,7 +455,7 @@ public: * */ grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g) - :domain(domain),ghost(g),dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster) + :domain(domain),ghost(g),dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { // check that the grid has valid size check_size(g_sz); @@ -433,6 +491,26 @@ public: dec.calculateGhostBoxes(); } + /*! \brief Get an object containing the grid informations + * + * \return an information object about this grid + * + */ + const grid_sm<dim,T> & getGridInfo() + { + return ginfo; + } + + /*! \brief Get an object containing the grid informations without type + * + * \return an information object about this grid + * + */ + const grid_sm<dim,void> & getGridInfoVoid() + { + return ginfo_v; + } + /*! \brief Get the object that store the information about the decomposition * * \return the decomposition object @@ -453,55 +531,6 @@ public: return cd_sm; } - /*! \brief Create the grids on memory - * - */ - void Create() - { - Box<dim,St> g_rnd_box; - for (size_t i = 0 ; i < dim ; i++) {g_rnd_box.setHigh(i,0.5); g_rnd_box.setLow(i,-0.5);} - - // Get the number of local grid needed - size_t n_grid = dec.getNLocalHyperCube(); - - // create local grids for each hyper-cube - loc_grid = v_cl.allocate<device_grid>(n_grid); - - // Size of the grid on each dimension - size_t l_res[dim]; - - // Allocate the grids - for (size_t i = 0 ; i < n_grid ; i++) - { - gdb_ext.add(); - - // Get the local hyper-cube - SpaceBox<dim,St> sp = dec.getLocalHyperCube(i); - SpaceBox<dim,St> sp_g = dec.getSubDomainWithGhost(i); - - // Convert from SpaceBox<dim,St> to SpaceBox<dim,long int> - SpaceBox<dim,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp); - SpaceBox<dim,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g); - - //! Save the origin of the sub-domain of the local grid - gdb_ext.last().origin = sp_tg.getP1(); - - // save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning) - // and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate - gdb_ext.last().Dbox = sp_t; - gdb_ext.last().Dbox -= sp_tg.getP1(); - - // center to zero - sp_tg -= sp_tg.getP1(); - - // Get the size of the local grid - for (size_t i = 0 ; i < dim ; i++) {l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;} - - // Set the dimensions of the local grid - loc_grid.get(i).resize(l_res); - } - } - /*! \brief Check that the global grid key is inside the grid domain * * \return true if is inside diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp index ca6d7fba0..73e04ad42 100644 --- a/src/Grid/grid_dist_id_unit_test.hpp +++ b/src/Grid/grid_dist_id_unit_test.hpp @@ -110,18 +110,21 @@ void Test2D_sub(const Box<2,float> & domain, long int k) bool val = g_dist.getDecomposition().check_consistency(); BOOST_REQUIRE_EQUAL(val,true); + size_t count; + // 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; + count = 0; + + // get the sub-domain iterator auto dom = g_dist.getSubDomainIterator(one,one_end); while (dom.isNext()) @@ -145,6 +148,8 @@ void Test2D_sub(const Box<2,float> & domain, long int k) //! [Usage of a sub_grid iterator] + } + // Get the virtual cluster machine Vcluster & vcl = g_dist.getVC(); @@ -154,6 +159,45 @@ void Test2D_sub(const Box<2,float> & domain, long int k) // Check BOOST_REQUIRE_EQUAL(count,(k-2)*(k-2)); + + // check with a 1x1 square + + { + + grid_key_dx<2> one(k/2,k/2); + grid_key_dx<2> one_end(k/2,k/2); + + count = 0; + + // get the sub-domain iterator + auto dom = g_dist.getSubDomainIterator(one,one_end); + + while (dom.isNext()) + { + auto key = dom.get(); + auto key_g = g_dist.getGKey(key); + + // key_g + BOOST_REQUIRE_EQUAL(key_g.get(0),k/2); + BOOST_REQUIRE_EQUAL(key_g.get(1),k/2); + + key_s_it = dom.getGKey(key); + + BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0)); + BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1)); + + // Count the point + count++; + + ++dom; + } + + // reduce + vcl.sum(count); + vcl.execute(); + + BOOST_REQUIRE_EQUAL(count,1); + } } } @@ -304,7 +348,11 @@ void Test3D_sub(const Box<3,float> & domain, long int k) // get the domain iterator size_t count = 0; - auto dom = g_dist.getDomainIterator(); + grid_key_dx<3> one(1,1,1); + grid_key_dx<3> one_end(k-2,k-2,k-2); + + // Sub-domain iterator + auto dom = g_dist.getSubDomainIterator(one,one_end); while (dom.isNext()) { @@ -327,51 +375,47 @@ void Test3D_sub(const Box<3,float> & domain, long int k) vcl.execute(); // Check - BOOST_REQUIRE_EQUAL(count,k*k*k); - - bool match = true; + BOOST_REQUIRE_EQUAL(count,(k-2)*(k-2)*(k-2)); - auto dom2 = g_dist.getDomainIterator(); - - // check that the grid store the correct information - while (dom2.isNext()) + // check with a 1x1x1 square { - 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; - } + grid_key_dx<3> one(k/2,k/2,k/2); + grid_key_dx<3> one_end(k/2,k/2,k/2); - BOOST_REQUIRE_EQUAL(match,true); + count = 0; - //! [Synchronize the ghost and check the information] + // get the sub-domain iterator + auto dom = g_dist.getSubDomainIterator(one,one_end); - g_dist.template ghost_get<0>(); + while (dom.isNext()) + { + auto key = dom.get(); + auto key_g = g_dist.getGKey(key); - // check that the communication is correctly completed + // key_g + BOOST_REQUIRE_EQUAL(key_g.get(0),k/2); + BOOST_REQUIRE_EQUAL(key_g.get(1),k/2); + BOOST_REQUIRE_EQUAL(key_g.get(2),k/2); - auto domg = g_dist.getDomainGhostIterator(); + auto key_s_it = dom.getGKey(key); - // 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); + BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0)); + BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1)); + BOOST_REQUIRE_EQUAL(key_g.get(2),key_s_it.get(2)); - // 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; - } + // Count the point + count++; - ++domg; + ++dom; } - BOOST_REQUIRE_EQUAL(match,true); + // reduce + vcl.sum(count); + vcl.execute(); - //! [Synchronize the ghost and check the information] + BOOST_REQUIRE_EQUAL(count,1); + } } } -- GitLab