diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index 45dfb9f1624cbeb6473b19ca65dcbe9e1f704f5c..dab7b09b6f8163a833241092e9f81377fc620876 100644 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -66,7 +66,7 @@ */ template<unsigned int dim, typename T, template<typename> class device_l=openfpm::device_cpu, typename Memory=HeapMemory, template<unsigned int, typename> class Domain=Box> -class CartDecomposition : public ie_loc_ghost<dim,T>, public nn_prcs<dim,T> +class CartDecomposition : public ie_loc_ghost<dim,T>, public nn_prcs<dim,T> , public ie_ghost<dim,T> { public: @@ -90,10 +90,10 @@ private: //! and for each processor contain the boxes calculated from the intersection //! of the sub-domains + ghost with the near-by processor sub-domain () and the other way around //! \see calculateGhostBoxes - openfpm::vector< openfpm::vector< Box_proc<dim,T> > > box_nn_processor_int; +// openfpm::vector< openfpm::vector< Box_proc<dim,T> > > box_nn_processor_int; //! It store the same information of box_nn_processor_int organized by processor id - openfpm::vector< Box_dom<dim,T> > proc_int_box; +// openfpm::vector< Box_dom<dim,T> > proc_int_box; //! for each sub-domain, contain the list of the neighborhood processors openfpm::vector<openfpm::vector<long unsigned int> > box_nn_processor; @@ -119,7 +119,7 @@ private: Vcluster & v_cl; //! Cell-list that store the geometrical information of the internal ghost boxes - CellList<dim,T,FAST> geo_cell; +// CellList<dim,T,FAST> geo_cell; //! Cell-list that store the geometrical information of the local internal ghost boxes CellList<dim,T,FAST> lgeo_cell; @@ -273,7 +273,7 @@ private: orig.get(i) = bound.getLow(i); // Initialize the geo_cell structure - geo_cell.Initialize(domain,div,orig); + ie_ghost<dim,T>::Initialize_geo_cell(domain,div,orig); lgeo_cell.Initialize(domain,div,orig); } @@ -330,7 +330,7 @@ private: * \see calculateGhostBoxes * */ - void create_box_nn_processor_ext(Ghost<dim,T> & ghost) +/* void create_box_nn_processor_ext(Ghost<dim,T> & ghost) { box_nn_processor_int.resize(sub_domains.size()); proc_int_box.resize(nn_prcs<dim,T>::getNNProcessors()); @@ -370,7 +370,7 @@ private: if (intersect == true) { - struct p_box pb; + struct p_box<dim,T> pb; pb.box = bi; pb.proc = p_id; @@ -409,7 +409,7 @@ private: } } } - } + }*/ /*! \brief Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box * @@ -423,7 +423,7 @@ private: * \see calculateGhostBoxes * */ - void create_box_nn_processor_int(Ghost<dim,T> & ghost) +/* void create_box_nn_processor_int(Ghost<dim,T> & ghost) { box_nn_processor_int.resize(sub_domains.size()); proc_int_box.resize(nn_prcs<dim,T>::getNNProcessors()); @@ -441,7 +441,7 @@ private: const openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_prcs<dim,T>::getAdjacentSubdomain(p_id); // get the local processor id - size_t lc_proc = nn_prcs<dim,T>::getAdjacentProcessor(p_id)/*nn_processor_subdomains[p_id].id*/; + size_t lc_proc = nn_prcs<dim,T>::getAdjacentProcessor(p_id); // For each near processor sub-domains enlarge and intersect with the local sub-domain and store the result for (size_t k = 0 ; k < nn_p_box.size() ; k++) @@ -457,7 +457,7 @@ private: n_sub.enlarge(ghost); // Intersect with the local sub-domain - p_box b_int; + p_box<dim,T> b_int; bool intersect = n_sub.Intersect(l_sub,b_int.box); // store if it intersect @@ -527,7 +527,7 @@ private: } } } - } + }*/ // Heap memory receiver HeapMemory hp_recv; @@ -581,29 +581,7 @@ public: ~CartDecomposition() {} - // It store all the boxes of the near processors in a linear array - struct p_box - { - //! Box that identify the intersection of the ghost of the near processor with the - //! processor sub-domain - ::Box<dim,T> box; - //! local processor id - size_t lc_proc; - //! processor id - size_t proc; - - /*! \brief Check if two p_box are the same - * - * \param pb box to check - * - */ - bool operator==(const p_box & pb) - { - return pb.lc_proc == lc_proc; - } - }; - - openfpm::vector<size_t> ids; +// openfpm::vector<size_t> ids; /*! \brief class to select the returned id by ghost_processorID * @@ -619,7 +597,7 @@ public: * \return box id * */ - inline static size_t id(p_box & p, size_t b_id) + inline static size_t id(p_box<dim,T> & p, size_t b_id) { return b_id; } @@ -639,7 +617,7 @@ public: * \return processor id * */ - inline static size_t id(p_box & p, size_t b_id) + inline static size_t id(p_box<dim,T> & p, size_t b_id) { return p.proc; } @@ -659,7 +637,7 @@ public: * \return local processor id * */ - inline static size_t id(p_box & p, size_t b_id) + inline static size_t id(p_box<dim,T> & p, size_t b_id) { return p.lc_proc; } @@ -671,14 +649,11 @@ public: * \return An iterator with the id's of the internal boxes in which the point fall * */ - auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) +/* auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) { return geo_cell.getIterator(geo_cell.getCell(p)); - } - + }*/ -#define UNIQUE 1 -#define MULTIPLE 2 /*! \brief Given a position it return if the position belong to any neighborhood processor ghost * (Internal ghost) @@ -692,7 +667,7 @@ public: * \param return the processor ids * */ - template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE) +/* template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE) { ids.clear(); @@ -719,7 +694,7 @@ public: ids.unique(); return ids; - } + }*/ /*! \brief Given a position it return if the position belong to any neighborhood processor ghost * (Internal ghost) @@ -730,7 +705,7 @@ public: * \param return the processor ids * */ - template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE) +/* template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE) { ids.clear(); @@ -757,14 +732,14 @@ public: ids.unique(); return ids; - } + }*/ // External ghost boxes for this processor, indicated with G8_0 G9_0 ... - openfpm::vector<p_box> vb_ext; +// openfpm::vector<p_box<dim,T>> vb_ext; // Internal ghost boxes for this processor domain, indicated with B8_0 B9_0 ..... in the figure // below as a linear vector - openfpm::vector<p_box> vb_int; +// openfpm::vector<p_box<dim,T>> vb_int; /*! It calculate the internal ghost boxes * @@ -865,8 +840,8 @@ p1[0]<-----+ +----> p2[0] // Intersect all the local sub-domains with the sub-domains of the contiguous processors // create the internal structures that store ghost information - create_box_nn_processor_ext(ghost); - create_box_nn_processor_int(ghost); + ie_ghost<dim,T>::create_box_nn_processor_ext(v_cl,ghost,sub_domains,box_nn_processor,*this); + ie_ghost<dim,T>::create_box_nn_processor_int(v_cl,ghost,sub_domains,box_nn_processor,*this); // ebox must come after ibox (in this case) @@ -1101,10 +1076,10 @@ p1[0]<-----+ +----> p2[0] * \return iterator of the processors id's * */ - inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) +/* inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) { return geo_cell.getIterator(geo_cell.getCell(p)); - } + }*/ ////////////// Functions to get decomposition information /////////////// @@ -1116,10 +1091,10 @@ p1[0]<-----+ +----> p2[0] * \return the number of internal ghost * */ - inline size_t getProcessorNIGhost(size_t id) const +/* inline size_t getProcessorNIGhost(size_t id) const { return proc_int_box.get(id).ibx.size(); - } + }*/ /*! \brief Get the number of External ghost boxes for one processor id * @@ -1127,10 +1102,10 @@ p1[0]<-----+ +----> p2[0] * \return the number of external ghost * */ - inline size_t getProcessorNEGhost(size_t id) const +/* inline size_t getProcessorNEGhost(size_t id) const { return proc_int_box.get(id).ebx.size(); - } + }*/ /*! \brief Get the j Internal ghost box for one processor * @@ -1139,10 +1114,10 @@ p1[0]<-----+ +----> p2[0] * \return the box * */ - inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const +/* inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const { return proc_int_box.get(id).ibx.get(j); - } + }*/ /*! \brief Get the j External ghost box * @@ -1151,10 +1126,10 @@ p1[0]<-----+ +----> p2[0] * \return the box * */ - inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const +/* inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const { return proc_int_box.get(id).ebx.get(j); - } + }*/ /*! \brief Get the j Internal ghost box id * @@ -1163,10 +1138,10 @@ p1[0]<-----+ +----> p2[0] * \return the box * */ - inline size_t getProcessorIGhostId(size_t id, size_t j) const +/* inline size_t getProcessorIGhostId(size_t id, size_t j) const { return proc_int_box.get(id).ibx.get(j).id; - } + }*/ /*! \brief Get the j External ghost box id * @@ -1175,10 +1150,10 @@ p1[0]<-----+ +----> p2[0] * \return the box * */ - inline size_t getProcessorEGhostId(size_t id, size_t j) const +/* inline size_t getProcessorEGhostId(size_t id, size_t j) const { return proc_int_box.get(id).ebx.get(j).id; - } + }*/ /*! \brief Get the local sub-domain at witch belong the internal ghost box @@ -1188,10 +1163,10 @@ p1[0]<-----+ +----> p2[0] * \return sub-domain at which belong the internal ghost box * */ - inline const size_t getProcessorIGhostSub(size_t id, size_t j) const +/* inline const size_t getProcessorIGhostSub(size_t id, size_t j) const { return proc_int_box.get(id).ibx.get(j).sub; - } + }*/ /*! \brief Get the local sub-domain at witch belong the external ghost box * @@ -1200,30 +1175,30 @@ p1[0]<-----+ +----> p2[0] * \return sub-domain at which belong the external ghost box * */ - inline const size_t getProcessorEGhostSub(size_t id, size_t j) const +/* inline const size_t getProcessorEGhostSub(size_t id, size_t j) const { return proc_int_box.get(id).ebx.get(j).sub; - } + }*/ /*! \brief Return the total number of the calculated internal ghost boxes * * \return the number of internal ghost boxes * */ - inline size_t getNIGhostBox() const +/* inline size_t getNIGhostBox() const { return vb_int.size(); - } + }*/ /*! \brief Given the internal ghost box id, it return the internal ghost box * * \return the internal ghost box * */ - inline ::Box<dim,T> getIGhostBox(size_t b_id) const +/* inline ::Box<dim,T> getIGhostBox(size_t b_id) const { return vb_int.get(b_id).box; - } + }*/ /*! \brief Given the internal ghost box id, it return the near processor at witch belong * or the near processor that produced this internal ghost box @@ -1231,30 +1206,30 @@ p1[0]<-----+ +----> p2[0] * \return the processor id of the ghost box * */ - inline size_t getIGhostBoxProcessor(size_t b_id) const +/* inline size_t getIGhostBoxProcessor(size_t b_id) const { return vb_int.get(b_id).proc; - } + }*/ /*! \brief Get the number of the calculated external ghost boxes * * \return the number of external ghost boxes * */ - inline size_t getNEGhostBox() const +/* inline size_t getNEGhostBox() const { return vb_ext.size(); - } + }*/ /*! \brief Given the external ghost box id, it return the external ghost box * * \return the external ghost box * */ - inline ::Box<dim,T> getEGhostBox(size_t b_id) const +/* inline ::Box<dim,T> getEGhostBox(size_t b_id) const { return vb_ext.get(b_id).box; - } + }*/ /*! \brief Given the external ghost box id, it return the near processor at witch belong * or the near processor that produced this external ghost box @@ -1262,10 +1237,10 @@ p1[0]<-----+ +----> p2[0] * \return the processor id of the external ghost box * */ - inline size_t getEGhostBoxProcessor(size_t b_id) const +/* inline size_t getEGhostBoxProcessor(size_t b_id) const { return vb_ext.get(b_id).proc; - } + }*/ /*! \brief Write the decomposition as VTK file * @@ -1293,7 +1268,7 @@ p1[0]<-----+ +----> p2[0] nn_prcs<dim,T>::write(output); //! internal_ghost_X.vtk Internal ghost boxes for the local processor (X) - VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3; +/* VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3; for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++) { for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++) @@ -1312,8 +1287,9 @@ p1[0]<-----+ +----> p2[0] vtk_box4.add(box_nn_processor_int.get(p).get(s).bx); } } - vtk_box4.write(output + std::string("external_ghost_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk")); + vtk_box4.write(output + std::string("external_ghost_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));*/ + ie_ghost<dim,T>::write(output,v_cl.getProcessUnitID()); ie_loc_ghost<dim,T>::write(output,v_cl.getProcessUnitID()); return true; @@ -1338,9 +1314,9 @@ p1[0]<-----+ +----> p2[0] for (size_t p = 0 ; p < nn_prcs<dim,T>::getNNProcessors() ; p++) { - for (size_t i = 0 ; i < getProcessorNEGhost(p) ; i++) + for (size_t i = 0 ; i < ie_ghost<dim,T>::getProcessorNEGhost(p) ; i++) { - std::cout << getProcessorEGhostBox(p,i).toString() << " prc=" << nn_prcs<dim,T>::IDtoProc(p) << " id=" << getProcessorEGhostId(p,i) << "\n"; + std::cout << ie_ghost<dim,T>::getProcessorEGhostBox(p,i).toString() << " prc=" << nn_prcs<dim,T>::IDtoProc(p) << " id=" << ie_ghost<dim,T>::getProcessorEGhostId(p,i) << "\n"; } } @@ -1348,9 +1324,9 @@ p1[0]<-----+ +----> p2[0] for (size_t p = 0 ; p < nn_prcs<dim,T>::getNNProcessors() ; p++) { - for (size_t i = 0 ; i < getProcessorNIGhost(p) ; i++) + for (size_t i = 0 ; i < ie_ghost<dim,T>::getProcessorNIGhost(p) ; i++) { - std::cout << getProcessorIGhostBox(p,i).toString() << " prc=" << nn_prcs<dim,T>::IDtoProc(p) << " id=" << getProcessorIGhostId(p,i) << "\n"; + std::cout << ie_ghost<dim,T>::getProcessorIGhostBox(p,i).toString() << " prc=" << nn_prcs<dim,T>::IDtoProc(p) << " id=" << ie_ghost<dim,T>::getProcessorIGhostId(p,i) << "\n"; } } } diff --git a/src/Decomposition/common.hpp b/src/Decomposition/common.hpp index 6387226a42fa41bca2a6021bda9eeab4d6c183bd..403820e7d5fc64b2b3fbdadc7d7d39d8acf8de5a 100644 --- a/src/Decomposition/common.hpp +++ b/src/Decomposition/common.hpp @@ -130,4 +130,27 @@ struct N_box typename openfpm::vector<::Box<dim,T>> bx; }; +// It store all the boxes of the near processors in a linear array +template<unsigned int dim, typename T> +struct p_box +{ + //! Box that identify the intersection of the ghost of the near processor with the + //! processor sub-domain + ::Box<dim,T> box; + //! local processor id + size_t lc_proc; + //! processor id + size_t proc; + + /*! \brief Check if two p_box are the same + * + * \param pb box to check + * + */ + bool operator==(const p_box & pb) + { + return pb.lc_proc == lc_proc; + } +}; + #endif /* SRC_DECOMPOSITION_COMMON_HPP_ */ diff --git a/src/Decomposition/ie_ghost.hpp b/src/Decomposition/ie_ghost.hpp index 76e9eb508d08967a3516a6407253ce49f0069f0c..deced3bb54cabdb80122cf995a8a30dbdcbf425b 100644 --- a/src/Decomposition/ie_ghost.hpp +++ b/src/Decomposition/ie_ghost.hpp @@ -9,6 +9,10 @@ #define SRC_DECOMPOSITION_IE_GHOST_HPP_ #include "common.hpp" +#include "nn_processor.hpp" + +#define UNIQUE 1 +#define MULTIPLE 2 /*! \brief structure that store and compute the internal and external local ghost box * @@ -30,6 +34,30 @@ class ie_ghost //! It store the same information of box_nn_processor_int organized by processor id openfpm::vector< Box_dom<dim,T> > proc_int_box; + // External ghost boxes for this processor, indicated with G8_0 G9_0 ... + openfpm::vector<p_box<dim,T> > vb_ext; + + // Internal ghost boxes for this processor domain, indicated with B8_0 B9_0 ..... in the figure + // below as a linear vector + openfpm::vector<p_box<dim,T> > vb_int; + + //! Cell-list that store the geometrical information of the internal ghost boxes + CellList<dim,T,FAST> geo_cell; + +protected: + + /*! \brief Initialize the geo cell list structure + * + * The geo cell list structure exist to speed up the labelling the points if they fall on some + * internal ghost + * + */ + void Initialize_geo_cell(const Box<dim,T> & domain, const size_t (&div)[dim] ,const Point<dim,T> & orig) + { + // Initialize the geo_cell structure + geo_cell.Initialize(domain,div,orig); + } + /*! \brief Create the box_nn_processor_int (bx part) structure * * This structure store for each sub-domain of this processors enlarged by the ghost size the boxes that @@ -41,10 +69,10 @@ class ie_ghost * \see calculateGhostBoxes * */ - void create_box_nn_processor_ext(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains) + void create_box_nn_processor_ext(Vcluster & v_cl, Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor, const nn_prcs<dim,T> & nn_p) { -/* box_nn_processor_int.resize(sub_domains.size()); - proc_int_box.resize(getNNProcessors()); + box_nn_processor_int.resize(sub_domains.size()); + proc_int_box.resize(nn_p.getNNProcessors()); // For each sub-domain for (size_t i = 0 ; i < sub_domains.size() ; i++) @@ -64,10 +92,10 @@ class ie_ghost size_t p_id = box_nn_processor.get(i).get(j); // store the box in proc_int_box storing from which sub-domain they come from - Box_dom & proc_int_box_g = proc_int_box.get(ProctoID(p_id)); + Box_dom<dim,T> & proc_int_box_g = proc_int_box.get(nn_p.ProctoID(p_id)); // get the set of sub-domains of the adjacent processor p_id - openfpm::vector< ::Box<dim,T> > & nn_processor_subdomains_g = nn_processor_subdomains[p_id].bx; + const openfpm::vector< ::Box<dim,T> > & nn_processor_subdomains_g = nn_p.getExternalAdjSubdomain(p_id).bx; // near processor sub-domain intersections openfpm::vector< ::Box<dim,T> > & box_nn_processor_int_gg = box_nn_processor_int.get(i).get(j).bx; @@ -81,11 +109,11 @@ class ie_ghost if (intersect == true) { - struct p_box pb; + struct p_box<dim,T> pb; pb.box = bi; pb.proc = p_id; - pb.lc_proc = ProctoID(p_id); + pb.lc_proc = nn_p.ProctoID(p_id); // // Updating @@ -105,20 +133,20 @@ class ie_ghost // Search for the correct id size_t k = 0; - size_t p_idp = ProctoID(p_id); - for (k = 0 ; k < proc_adj_box.get(p_idp).size() ; k++) + size_t p_idp = nn_p.ProctoID(p_id); + for (k = 0 ; k < nn_p.getInternalAdjSubdomain(p_idp).size() ; k++) { - if (proc_adj_box.get(p_idp).get(k) == i) + if (nn_p.getInternalAdjSubdomain(p_idp).get(k) == i) break; } - if (k == proc_adj_box.get(p_idp).size()) + if (k == nn_p.getInternalAdjSubdomain(p_idp).size()) std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n"; proc_int_box_g.ebx.last().id = (k * nn_processor_subdomains_g.size() + b) * v_cl.getProcessingUnits() + p_id; } } } - }*/ + } } /*! \brief Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box @@ -127,13 +155,18 @@ class ie_ghost * of the near processors sub-domains enlarged by the ghost size (Internal ghost box). These boxes * fill a geometrical cell list. The proc_int_box store the same information ordered by near processors * + * \param v_cl Virtual cluster * \param ghost margins + * \param sub_domains + * \param box_nn_processors sub-domains of the adjacent processors + * \param nn_prcs structure that store the adjacent processor information + * \param geo_cell Cell list that store the subdomain information * * \note Are the B8_0 B9_0 B9_1 B5_0 boxes in calculateGhostBoxes * \see calculateGhostBoxes * */ - void create_box_nn_processor_int(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processors, const nn_prcs<dim,T> & nn_p ) + void create_box_nn_processor_int(Vcluster & v_cl, Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor, const nn_prcs<dim,T> & nn_p) { box_nn_processor_int.resize(sub_domains.size()); proc_int_box.resize(nn_p.getNNProcessors()); @@ -148,10 +181,10 @@ class ie_ghost size_t p_id = box_nn_processor.get(i).get(j); // get the set of sub-domains of the contiguous processor p_id - openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_p.get nn_processor_subdomains[p_id].bx; + const openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_p.getExternalAdjSubdomain(p_id).bx; // get the local processor id - size_t lc_proc = nn_processor_subdomains[p_id].id; + size_t lc_proc = nn_p.getAdjacentProcessor(p_id); // For each near processor sub-domains enlarge and intersect with the local sub-domain and store the result for (size_t k = 0 ; k < nn_p_box.size() ; k++) @@ -167,7 +200,7 @@ class ie_ghost n_sub.enlarge(ghost); // Intersect with the local sub-domain - p_box b_int; + p_box<dim,T> b_int; bool intersect = n_sub.Intersect(l_sub,b_int.box); // store if it intersect @@ -196,23 +229,23 @@ class ie_ghost vb_int.add(b_int); // store the box in proc_int_box storing from which sub-domain they come from - Box_dom & pr_box_int = proc_int_box.get(ProctoID(p_id)); + Box_dom<dim,T> & pr_box_int = proc_int_box.get(nn_p.ProctoID(p_id)); Box_sub<dim,T> sb; sb = b_int.box; sb.sub = i; // Search for the correct id size_t s = 0; - size_t p_idp = ProctoID(p_id); - for (s = 0 ; s < proc_adj_box.get(p_idp).size() ; s++) + size_t p_idp = nn_p.ProctoID(p_id); + for (s = 0 ; s < nn_p.getInternalAdjSubdomain(p_idp).size() ; s++) { - if (proc_adj_box.get(p_idp).get(s) == i) + if (nn_p.getInternalAdjSubdomain(p_idp).get(s) == i) break; } - if (s == proc_adj_box.get(p_idp).size()) + if (s == nn_p.getInternalAdjSubdomain(p_idp).size()) std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n"; - sb.id = (k * proc_adj_box.get(p_idp).size() + s) * v_cl.getProcessingUnits() + v_cl.getProcessUnitID(); + sb.id = (k * nn_p.getInternalAdjSubdomain(p_idp).size() + s) * v_cl.getProcessingUnits() + v_cl.getProcessUnitID(); pr_box_int.ibx.add(sb); @@ -238,6 +271,305 @@ class ie_ghost } } } + +public: + + /*! \brief Get the number of Internal ghost boxes for one processor + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \return the number of internal ghost + * + */ + inline size_t getProcessorNIGhost(size_t id) const + { + return proc_int_box.get(id).ibx.size(); + } + + /*! \brief Get the number of External ghost boxes for one processor id + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \return the number of external ghost + * + */ + inline size_t getProcessorNEGhost(size_t id) const + { + return proc_int_box.get(id).ebx.size(); + } + + /*! \brief Get the j Internal ghost box for one processor + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one internal ghost box) + * \return the box + * + */ + inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const + { + return proc_int_box.get(id).ibx.get(j); + } + + /*! \brief Get the j External ghost box + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one external ghost box) + * \return the box + * + */ + inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const + { + return proc_int_box.get(id).ebx.get(j); + } + + /*! \brief Get the j Internal ghost box id + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one internal ghost box) + * \return the box + * + */ + inline size_t getProcessorIGhostId(size_t id, size_t j) const + { + return proc_int_box.get(id).ibx.get(j).id; + } + + /*! \brief Get the j External ghost box id + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one external ghost box) + * \return the box + * + */ + inline size_t getProcessorEGhostId(size_t id, size_t j) const + { + return proc_int_box.get(id).ebx.get(j).id; + } + + + /*! \brief Get the local sub-domain at witch belong the internal ghost box + * + * \param id adjacent processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one internal ghost box) + * \return sub-domain at which belong the internal ghost box + * + */ + inline const size_t getProcessorIGhostSub(size_t id, size_t j) const + { + return proc_int_box.get(id).ibx.get(j).sub; + } + + /*! \brief Get the local sub-domain at witch belong the external ghost box + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one external ghost box) + * \return sub-domain at which belong the external ghost box + * + */ + inline const size_t getProcessorEGhostSub(size_t id, size_t j) const + { + return proc_int_box.get(id).ebx.get(j).sub; + } + + /*! \brief Return the total number of the calculated internal ghost boxes + * + * \return the number of internal ghost boxes + * + */ + inline size_t getNIGhostBox() const + { + return vb_int.size(); + } + + /*! \brief Given the internal ghost box id, it return the internal ghost box + * + * \return the internal ghost box + * + */ + inline ::Box<dim,T> getIGhostBox(size_t b_id) const + { + return vb_int.get(b_id).box; + } + + /*! \brief Given the internal ghost box id, it return the near processor at witch belong + * or the near processor that produced this internal ghost box + * + * \return the processor id of the ghost box + * + */ + inline size_t getIGhostBoxProcessor(size_t b_id) const + { + return vb_int.get(b_id).proc; + } + + /*! \brief Get the number of the calculated external ghost boxes + * + * \return the number of external ghost boxes + * + */ + inline size_t getNEGhostBox() const + { + return vb_ext.size(); + } + + /*! \brief Given the external ghost box id, it return the external ghost box + * + * \return the external ghost box + * + */ + inline ::Box<dim,T> getEGhostBox(size_t b_id) const + { + return vb_ext.get(b_id).box; + } + + /*! \brief Given the external ghost box id, it return the near processor at witch belong + * or the near processor that produced this external ghost box + * + * \return the processor id of the external ghost box + * + */ + inline size_t getEGhostBoxProcessor(size_t b_id) const + { + return vb_ext.get(b_id).proc; + } + + /*! /brief Given a point it return the set of boxes in which the point fall + * + * \param p Point to check + * \return An iterator with the id's of the internal boxes in which the point fall + * + */ + auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) + { + return geo_cell.getIterator(geo_cell.getCell(p)); + } + + /*! \brief if the point fall into the ghost of some near processor it return the processors id's in which + * it fall + * + * \param p Point + * \return iterator of the processors id's + * + */ + inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p))) + { + return geo_cell.getIterator(geo_cell.getCell(p)); + } + + openfpm::vector<size_t> ids; + + /*! \brief Given a position it return if the position belong to any neighborhood processor ghost + * (Internal ghost) + * + * \tparam id type of if to get box_id processor_id lc_processor_id + * \param p Particle position + * \param opt intersection boxes of the same processor can overlap, so in general the function + * can produce more entry with the same processor, the UNIQUE option eliminate double entries + * (UNIQUE) is for particle data (MULTIPLE) is for grid data [default MULTIPLE] + * + * \param return the processor ids + * + */ + template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE) + { + ids.clear(); + + // Check with geo-cell if a particle is inside one Cell containing boxes + + auto cell_it = geo_cell.getIterator(geo_cell.getCell(p)); + + // For each element in the cell, check if the point is inside the box + // if it is, store the processor id + while (cell_it.isNext()) + { + size_t bid = cell_it.get(); + + if (vb_int.get(bid).box.isInside(p) == true) + { + ids.add(id::id(vb_int.get(bid),bid)); + } + + ++cell_it; + } + + // Make the id unique + if (opt == UNIQUE) + ids.unique(); + + return ids; + } + + /*! \brief Given a position it return if the position belong to any neighborhood processor ghost + * (Internal ghost) + * + * \tparam id type of if to get box_id processor_id lc_processor_id + * \param p Particle position + * + * \param return the processor ids + * + */ + template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE) + { + ids.clear(); + + // Check with geo-cell if a particle is inside one Cell containing boxes + + auto cell_it = geo_cell.getIterator(geo_cell.getCell(p)); + + // For each element in the cell, check if the point is inside the box + // if it is, store the processor id + while (cell_it.isNext()) + { + size_t bid = cell_it.get(); + + if (vb_int.get(bid).box.isInside(p) == true) + { + ids.add(id::id(vb_int.get(bid),bid)); + } + + ++cell_it; + } + + // Make the id unique + if (opt == UNIQUE) + ids.unique(); + + return ids; + } + + /*! \brief write the information about the ghost in vtk format + * + * 1) internal_ghost_X.vtk Internal ghost boxes for the local processor (X) + * 2) external_ghost_X.vtk External ghost boxes for the local processor (X) + * + * \param output directory + * \param p_id processor rank + * + */ + bool write(std::string output, size_t p_id) const + { + //! internal_ghost_X.vtk Internal ghost boxes for the local processor (X) + VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3; + for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++) + { + for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++) + { + vtk_box3.add(box_nn_processor_int.get(p).get(s).nbx); + } + } + vtk_box3.write(output + std::string("internal_ghost_") + std::to_string(p_id) + std::string(".vtk")); + + //! external_ghost_X.vtk External ghost boxes for the local processor (X) + VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box4; + for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++) + { + for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++) + { + vtk_box4.add(box_nn_processor_int.get(p).get(s).bx); + } + } + vtk_box4.write(output + std::string("external_ghost_") + std::to_string(p_id) + std::string(".vtk")); + + return true; + } }; diff --git a/src/Decomposition/nn_processor.hpp b/src/Decomposition/nn_processor.hpp index b432881744e0c410e6522bc66a9e5129ab0e4511..b11a758196ffe9f51d03c1d03f8fc427e6b0a5b3 100644 --- a/src/Decomposition/nn_processor.hpp +++ b/src/Decomposition/nn_processor.hpp @@ -138,7 +138,7 @@ public: * \return return the processor rank * */ - inline size_t IDtoProc(size_t id) + inline size_t IDtoProc(size_t id) const { return nn_processors.get(id); } @@ -150,9 +150,16 @@ public: * \return the sub-domains * */ - inline const openfpm::vector< ::Box<dim,T> > & getAdjacentSubdomain(size_t p_id) + inline const openfpm::vector< ::Box<dim,T> > & getAdjacentSubdomain(size_t p_id) const { - return nn_processor_subdomains[p_id].bx; + auto key = nn_processor_subdomains.find(p_id); +#ifdef DEBUG + if (key == nn_processor_subdomains.end()) + { + std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor"; + } +#endif + return key->second.bx; } /*! \brief Get the adjacent processor id @@ -162,9 +169,16 @@ public: * \return the processor rank * */ - inline size_t getAdjacentProcessor(size_t p_id) + inline size_t getAdjacentProcessor(size_t p_id) const { - return nn_processor_subdomains[p_id].id; + auto key = nn_processor_subdomains.find(p_id); +#ifdef DEBUG + if (key == nn_processor_subdomains.end()) + { + std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor"; + } +#endif + return key->second.id; } @@ -175,11 +189,29 @@ public: * \return the sub-domains * */ - inline const openfpm::vector<size_t> & getInternalAdjSubdomain(size_t p_id) + inline const openfpm::vector<size_t> & getInternalAdjSubdomain(size_t p_id) const { return proc_adj_box.get(p_id); } + /*! \brief Get the external sub-domain adjacent to a processor p_id + * + * \param p_id processor rank + * \return the set of adjacent sub-domain comming from the processor p_id + * + */ + inline const N_box<dim,T> getExternalAdjSubdomain(size_t p_id) const + { + auto key = nn_processor_subdomains.find(p_id); +#ifdef DEBUG + if (key == nn_processor_subdomains.end()) + { + std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor"; + } +#endif + return key->second; + } + /*! \brief Convert the processor rank to the id in the list * * \param p processor rank @@ -187,9 +219,17 @@ public: * \return the id * */ - inline size_t ProctoID(size_t p) + inline size_t ProctoID(size_t p) const { - return nn_processor_subdomains[p].id; + auto key = nn_processor_subdomains.find(p); +#ifdef DEBUG + if (key == nn_processor_subdomains.end()) + { + std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor"; + } +#endif + + return key->second.id; } /*! \brief Write the decomposition as VTK file