From ed634ca877baf88c26b76f9f7f0823866fcf3246 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <i-bird@private-incardon-3.mpi-cbg.de> Date: Wed, 13 Apr 2016 09:55:27 +0200 Subject: [PATCH] Some small refactorization --- src/FiniteDifference/FDScheme.hpp | 100 +++++++++++++++++++++-- src/FiniteDifference/eq_unit_test.hpp | 26 ++++-- src/FiniteDifference/eq_unit_test_3d.hpp | 5 +- src/Vector/Vector_eigen.hpp | 83 ------------------- 4 files changed, 116 insertions(+), 98 deletions(-) diff --git a/src/FiniteDifference/FDScheme.hpp b/src/FiniteDifference/FDScheme.hpp index 5e5119ec..32b12e3c 100644 --- a/src/FiniteDifference/FDScheme.hpp +++ b/src/FiniteDifference/FDScheme.hpp @@ -18,13 +18,13 @@ /*! \brief Finite Differences * - * This class is able to discreatize on a Matrix any system of equations producing a linear system of type \f$Ax=B\f$. In order to create a consistent - * Matrix it is required that each processor must contain a contiguos range on grid points without - * holes. In order to ensure this, each processor produce a contiguos local labelling of its local + * This class is able to discretize on a Matrix any system of equations producing a linear system of type \f$Ax=b\f$. In order to create a consistent + * Matrix it is required that each processor must contain a contiguous range on grid points without + * holes. In order to ensure this, each processor produce a contiguous local labeling of its local * points. Each processor also add an offset equal to the number of local * points of the processors with id smaller than him, to produce a global and non overlapping - * labelling. An example is shown in the figures down, here we have - * a grid 8x6 divided across two processor each processor label locally its grid points + * labeling. An example is shown in the figures down, here we have + * a grid 8x6 divided across four processors each processor label locally its grid points * * \verbatim * @@ -266,6 +266,56 @@ private: } } + /*! \brief Copy a given solution vector in a staggered grid + * + * \tparam Vct Vector type + * \tparam Grid_dst target grid + * \tparam pos set of properties + * + * \param v Vector + * \param g_dst target staggered grid + * + */ + template<typename Vct, typename Grid_dst ,unsigned int ... pos> void copy_staggered(Vct & v, Grid_dst & g_dst) + { + // check that g_dst is staggered + if (g_dst.is_staggered() == false) + std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be staggered " << std::endl; + +#ifdef SE_CLASS1 + + if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize()) + std::cerr << __FILE__ << ":" << __LINE__ << " The staggered and destination grid in size does not match " << 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 Eigen 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; + } + } + public: /*! \brief set the staggered position for each property @@ -387,6 +437,7 @@ public: * Ax = b * * ## Stokes equation, lid driven cavity with one splipping wall + * \snippet eq_unit_test.hpp lid-driven cavity 2D * * \param op Operator to impose (A term) * \param num right hand side of the term (b term) @@ -412,7 +463,8 @@ public: * * Ax = b * - * ## Stokes equation, lid driven cavity with one splipping wall + * ## 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) @@ -513,6 +565,42 @@ public: return b; } + + /*! \brief Copy the vector into the grid + * + * ## Copy the solution into the grid + * \snippet eq_unit_test.hpp Copy the solution to grid + * + * \tparam scheme Discretization scheme + * \tparam Grid_dst type of the target grid + * \tparam pos target properties + * + * \param scheme Discretization scheme + * \param start point + * \param stop point + * \param g_dst Destination grid + * + */ + template<unsigned int ... pos, typename Vct, typename Grid_dst> void copy(Vct & v,const long int (& start)[Sys_eqs_typ::dims], const long int (& stop)[Sys_eqs_typ::dims], Grid_dst & g_dst) + { + if (is_grid_staggered<Sys_eqs>::value()) + { + if (g_dst.is_staggered() == true) + copy_staggered<Vct,Grid_dst,pos...>(v,g_dst); + else + { + // 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()); + stg.setDefaultStagPosition(); + copy_staggered<Vct,decltype(stg),pos...>(v,stg); + + // sync the ghost and interpolate to the normal grid + stg.template ghost_get<pos...>(); + stg.template to_normal<Grid_dst,pos...>(g_dst,this->getPadding(),start,stop); + } + } + } }; #define EQS_FIELDS 0 diff --git a/src/FiniteDifference/eq_unit_test.hpp b/src/FiniteDifference/eq_unit_test.hpp index 8aff09c9..511e5d01 100644 --- a/src/FiniteDifference/eq_unit_test.hpp +++ b/src/FiniteDifference/eq_unit_test.hpp @@ -39,18 +39,18 @@ struct lid_nn typedef float stype; // type of base grid, it is the distributed grid that will store the result - // Note the first property is a 2D vector (velocity), the second is a scalar + // Note the first property is a 2D vector (velocity), the second is a scalar (Pressure) typedef grid_dist_id<2,float,aggregate<float[2],float>,CartDecomposition<2,float>> b_grid; // type of SparseMatrix, for the linear system, this parameter is bounded by the solver - // that you are using + // that you are using, in case of umfpack it is the only possible choice typedef SparseMatrix<double,int> SparseMatrix_type; // type of Vector for the linear system, this parameter is bounded by the solver - // that you are using + // that you are using, in case of umfpack it is the only possible choice typedef Vector<double> Vector_type; - // Define that the underline grid where we discretize the operators is staggered + // Define that the underline grid where we discretize the system of equation is staggered static const int grid_type = STAGGERED_GRID; }; @@ -142,8 +142,15 @@ BOOST_AUTO_TEST_CASE(lid_driven_cavity) { Vcluster & v_cl = *global_v_cluster; + if (v_cl.getProcessingUnits() > 3) + return; + //! [lid-driven cavity 2D] + // velocity in the grid is the property 0, pressure is the property 1 + constexpr int velocity = 0; + constexpr int pressure = 1; + // Domain, a rectangle Box<2,float> domain({0.0,0.0},{3.0,1.0}); @@ -168,7 +175,7 @@ BOOST_AUTO_TEST_CASE(lid_driven_cavity) // Distributed grid that store the solution grid_dist_id<2,float,aggregate<float[2],float>,CartDecomposition<2,float>> g_dist(szu,domain,g); - // Ghost stencil + // It is the maximum extension of the stencil Ghost<2,long int> stencil_max(1); // Finite difference scheme @@ -219,11 +226,14 @@ BOOST_AUTO_TEST_CASE(lid_driven_cavity) auto x = umfpack_solver<double>::solve(fd.getA(),fd.getB()); - // Copy the solution to grid - x.copy<FDScheme<lid_nn>,decltype(g_dist),0,1>(fd,{0,0},{sz[0]-1,sz[1]-1},g_dist); - //! [lid-driven cavity 2D] + //! [Copy the solution to grid] + + fd.copy<velocity,pressure>(x,{0,0},{sz[0]-1,sz[1]-1},g_dist); + + //! [Copy the solution to grid] + g_dist.write("lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits())); if (v_cl.getProcessUnitID() == 0) diff --git a/src/FiniteDifference/eq_unit_test_3d.hpp b/src/FiniteDifference/eq_unit_test_3d.hpp index 2bae893d..cb6defb1 100644 --- a/src/FiniteDifference/eq_unit_test_3d.hpp +++ b/src/FiniteDifference/eq_unit_test_3d.hpp @@ -132,6 +132,9 @@ BOOST_AUTO_TEST_CASE(lid_driven_cavity) { Vcluster & v_cl = *global_v_cluster; + if (v_cl.getProcessingUnits() > 3) + return; + // Domain Box<3,float> domain({0.0,0.0,0.0},{3.0,1.0,1.0}); @@ -231,7 +234,7 @@ BOOST_AUTO_TEST_CASE(lid_driven_cavity) auto x = umfpack_solver<double>::solve(fd.getA(),fd.getB()); // Bring the solution to grid - x.copy<FDScheme<lid_nn_3d>,decltype(g_dist),velocity,pressure>(fd,{0,0},{sz[0]-1,sz[1]-1,sz[2]-1},g_dist); + fd.copy<velocity,pressure>(x,{0,0},{sz[0]-1,sz[1]-1,sz[2]-1},g_dist); g_dist.write("lid_driven_cavity_3d_p" + std::to_string(v_cl.getProcessingUnits())); diff --git a/src/Vector/Vector_eigen.hpp b/src/Vector/Vector_eigen.hpp index 57e1c690..b0d161e7 100644 --- a/src/Vector/Vector_eigen.hpp +++ b/src/Vector/Vector_eigen.hpp @@ -88,53 +88,6 @@ class Vector<T,Eigen::Matrix<T, Eigen::Dynamic, 1>> //size of each chunk mutable openfpm::vector<size_t> sz; - /*! \brief Copy in a staggered grid - * - * - */ - template<typename scheme, typename Grid_dst ,unsigned int ... pos> void copy_staggered_to_staggered(scheme & sc, Grid_dst & g_dst) - { - // get the map - const auto & g_map = sc.getMap(); - - // check that g_dst is staggered - if (is_grid_staggered<Grid_dst>::value() == false) - std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be staggered " << std::endl; - -#ifdef SE_CLASS1 - - if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize()) - std::cerr << __FILE__ << ":" << __LINE__ << " The staggered and destination grid in size does not match " << 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 Eigen vector - - copy_ele<typename scheme::Sys_eqs_typ,Grid_dst,typename std::remove_reference<decltype(*this)>::type> cp(key_dst,g_dst,*this,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 Here we collect the full matrix on master * @@ -350,42 +303,6 @@ public: return v; } - /*! \brief Copy the vector into the grid - * - * ## Copy from the vector to the destination grid - * \snippet eq_unit_tests.hpp - * - * \tparam scheme Discretization scheme - * \tparam Grid_dst type of the target grid - * \tparam pos target properties - * - * \param scheme Discretization scheme - * \param start point - * \param stop point - * \param g_dst Destination grid - * - */ - template<typename scheme, typename Grid_dst ,unsigned int ... pos> void copy(scheme & sc,const long int (& start)[scheme::Sys_eqs_typ::dims], const long int (& stop)[scheme::Sys_eqs_typ::dims], Grid_dst & g_dst) - { - if (is_grid_staggered<typename scheme::Sys_eqs_typ>::value()) - { - if (g_dst.is_staggered() == true) - copy_staggered_to_staggered<scheme,Grid_dst,pos...>(sc,g_dst); - else - { - // Create a temporal staggered grid and copy the data there - auto & g_map = sc.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(),sc.getPadding()); - stg.setDefaultStagPosition(); - copy_staggered_to_staggered<scheme,decltype(stg),pos...>(sc,stg); - - // sync the ghost and interpolate to the normal grid - stg.template ghost_get<pos...>(); - stg.template to_normal<Grid_dst,pos...>(g_dst,sc.getPadding(),start,stop); - } - } - } - /*! \brief Scatter the vector information to the other processors * * Eigen does not have a real parallel vector, so in order to work we have to scatter -- GitLab