/* * ie_ghost.hpp * * Created on: Aug 8, 2015 * Author: i-bird */ #ifndef SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_ #define SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_ #include "Space/Shape/Box.hpp" #include "Space/Ghost.hpp" #include "Space/SpaceBox.hpp" #include "common.hpp" #include "VTKWriter.hpp" /*! \brief structure that store and compute the internal and external local ghost box * * \tparam dim is the dimensionality of the physical domain we are going to decompose. * \tparam T type of the space we decompose, Real, Integer, Complex ... * * \see CartDecomposition * */ template<unsigned int dim, typename T> class ie_loc_ghost { openfpm::vector<lBox_dom<dim,T>> loc_ghost_box; // Save the ghost boundaries // Ghost<dim,T> ghost; protected: /*! \brief Create the external local ghost boxes * * \param ghost margin to enlarge * \param local sub-domain * */ void create_loc_ghost_ebox(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains) { // Save the ghost // this->ghost = ghost; loc_ghost_box.resize(sub_domains.size()); // For each sub-domain for (size_t i = 0 ; i < sub_domains.size() ; i++) { SpaceBox<dim,T> sub_with_ghost = sub_domains.get(i); // enlarge the sub-domain with the ghost sub_with_ghost.enlarge(ghost); // intersect with the other local sub-domains for (size_t j = 0 ; j < sub_domains.size() ; j++) { if (i == j) continue; ::Box<dim,T> bi; bool intersect = sub_with_ghost.Intersect(::SpaceBox<dim,T>(sub_domains.get(j)),bi); if (intersect == true) { Box_sub<dim,T> b; b.sub = j; b = bi; // local external ghost box loc_ghost_box.get(i).ebx.add(b); // search this box in the internal box of the sub-domain j for (size_t k = 0; k < loc_ghost_box.get(j).ibx.size() ; k++) { if (loc_ghost_box.get(j).ibx.get(k).sub == i) { loc_ghost_box.get(j).ibx.get(k).k = loc_ghost_box.get(i).ebx.size()-1; break; } } } } } } /*! \brief Create the internal local ghost boxes * * \param ghost margin to enlarge * */ void create_loc_ghost_ibox(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains) { loc_ghost_box.resize(sub_domains.size()); // For each sub-domain for (size_t i = 0 ; i < sub_domains.size() ; i++) { // intersect with the others local sub-domains for (size_t j = 0 ; j < sub_domains.size() ; j++) { if (i == j) continue; SpaceBox<dim,T> sub_with_ghost = sub_domains.get(j); // enlarge the sub-domain with the ghost sub_with_ghost.enlarge(ghost); ::Box<dim,T> bi; bool intersect = sub_with_ghost.Intersect(::SpaceBox<dim,T>(sub_domains.get(i)),bi); if (intersect == true) { Box_sub_k<dim,T> b; b.sub = j; b = bi; b.k = -1; loc_ghost_box.get(i).ibx.add(b); } } } } public: /*! \brief Get the number of external local ghost box for each sub-domain * * \param id sub-domain id * * \return the number of internal ghost box * */ inline size_t getLocalNEGhost(size_t id) { return loc_ghost_box.get(id).ebx.size(); } /*! \brief Get the number of internal local ghost box for each sub-domain * * \param id sub-domain id * * \return the number of external ghost box * */ inline size_t getLocalNIGhost(size_t id) { return loc_ghost_box.get(id).ibx.size(); } /*! \brief For the sub-domain i intersected with the sub-domain j enlarged, the associated * external ghost box is located in getLocalIGhostBox(j,k) with * getLocalIGhostSub(j,k) == i, this function return k * * */ inline size_t getLocalIGhostE(size_t i, size_t j) { return loc_ghost_box.get(i).ibx.get(j).k; } /*! \brief Get the j internal local ghost box for the i sub-domain of the local processor * * \note For the sub-domain i intersected with the sub-domain j enlarged, the associated * external ghost box is located in getLocalIGhostBox(j,k) with * getLocalIGhostSub(j,k) == i * * To get k use getLocalIGhostE * * \see getLocalIGhostE * * \param i sub-domain * \param j box * \return the box * */ inline const ::Box<dim,T> & getLocalIGhostBox(size_t i, size_t j) const { return loc_ghost_box.get(i).ibx.get(j); } /*! \brief Get the j external local ghost box for the local processor * * \param i sub-domain * \param j box * \return the box * */ inline const ::Box<dim,T> & getLocalEGhostBox(size_t i, size_t j) const { return loc_ghost_box.get(i).ebx.get(j); } /*! \brief Considering that sub-domain has N internal local ghost box identified * with the 0 <= k < N that come from the intersection of 2 sub-domains i and j * where j is enlarged, given the sub-domain i and the id k, it return the id of * the other sub-domain that produced the intersection * * \param i sub-domain * \param k id * \return the box * */ inline size_t getLocalIGhostSub(size_t i, size_t j) const { return loc_ghost_box.get(i).ibx.get(j).sub; } /*! \brief Considering that sub-domain has N external local ghost box identified * with the 0 <= k < N that come from the intersection of 2 sub-domains i and j * where j is enlarged, given the sub-domain i and the id k, it return the id of * the other sub-domain that produced the intersection * * \param i sub-domain * \param k id * \return the box * */ inline size_t getLocalEGhostSub(size_t i, size_t j) const { return loc_ghost_box.get(i).ebx.get(j).sub; } /*! \brief Write the decomposition as VTK file * * The function generate several files * * 5) local_internal_ghost_X.vtk internal local ghost boxes for the local processor (X) * 6) local_external_ghost_X.vtk external local ghost boxes for the local processor (X) * * where X is the local processor rank * * \param output directory where to write the files * \param p_id id of the local processor * */ bool write(std::string output, size_t p_id) const { //! local_internal_ghost_X.vtk internal local ghost boxes for the local processor (X) VTKWriter<openfpm::vector_std<Box_sub_k<dim,T>>,VECTOR_BOX> vtk_box5; for (size_t p = 0 ; p < loc_ghost_box.size() ; p++) { vtk_box5.add(loc_ghost_box.get(p).ibx); } vtk_box5.write(output + std::string("local_internal_ghost_") + std::to_string(p_id) + std::string(".vtk")); //! local_external_ghost_X.vtk external local ghost boxes for the local processor (X) VTKWriter<openfpm::vector_std<Box_sub<dim,T>>,VECTOR_BOX> vtk_box6; for (size_t p = 0 ; p < loc_ghost_box.size() ; p++) { vtk_box6.add(loc_ghost_box.get(p).ebx); } vtk_box6.write(output + std::string("local_external_ghost_") + std::to_string(p_id) + std::string(".vtk")); return true; } /*! \brief function to check the consistency of the information of the decomposition * * \param n_sub Number of sub_domain * * \return false if is inconsistent * */ bool check_consistency(size_t n_sub) { //! for each sub-domain for (size_t i = 0 ; i < loc_ghost_box.size() ; i++) { for (size_t j = 0 ; j < loc_ghost_box.get(i).ibx.size() ; j++) { if (loc_ghost_box.get(i).ibx.get(j).k == -1) return false; } } if (n_sub > 1) { for (size_t i = 0 ; i < loc_ghost_box.size() ; i++) { if (loc_ghost_box.get(i).ibx.size() == 0) return false; if (loc_ghost_box.get(i).ebx.size() == 0) return false; } } return true; } }; #endif /* SRC_DECOMPOSITION_GHOST_DEC_IE_GHOST_HPP_ */