20 #ifndef LIBMESH_PARALLEL_GHOST_SYNC_H 21 #define LIBMESH_PARALLEL_GHOST_SYNC_H 24 #include "libmesh/elem.h" 25 #include "libmesh/int_range.h" 26 #include "libmesh/location_maps.h" 27 #include "libmesh/mesh_base.h" 28 #include "libmesh/parallel_algebra.h" 66 template <
typename Iterator,
70 const Iterator & range_begin,
71 const Iterator & range_end,
72 LocationMap<DofObjType> & location_map,
88 template <
typename Iterator,
91 const Iterator & range_begin,
92 const Iterator & range_end,
102 template <
typename Iterator,
103 typename DofObjectCheckFunctor,
104 typename SyncFunctor>
106 const Iterator & range_begin,
107 const Iterator & range_end,
108 const DofObjectCheckFunctor & dofobj_check,
125 template <
typename Iterator,
126 typename SyncFunctor>
128 const Iterator & range_begin,
129 const Iterator & range_end,
162 template <
typename ElemCheckFunctor,
163 typename NodeCheckFunctor,
164 typename SyncFunctor>
166 const MeshBase::const_element_iterator & range_begin,
167 const MeshBase::const_element_iterator & range_end,
168 const ElemCheckFunctor & elem_check,
169 const NodeCheckFunctor & node_check,
209 template <
typename ElemCheckFunctor,
210 typename NodeCheckFunctor,
211 typename SyncFunctor>
213 const MeshBase::const_element_iterator & range_begin,
214 const MeshBase::const_element_iterator & range_end,
215 const ElemCheckFunctor & elem_check,
216 const NodeCheckFunctor & node_check,
237 template <
typename Iterator,
239 typename SyncFunctor>
241 const Iterator & range_begin,
242 const Iterator & range_end,
247 libmesh_parallel_only(comm);
251 bool need_map_update = (range_begin != range_end && location_map.
empty());
252 comm.
max(need_map_update);
257 std::map<processor_id_type, dof_id_type>
258 ghost_objects_from_proc;
260 for (Iterator it = range_begin; it != range_end; ++it)
262 DofObjType * obj = *it;
266 ghost_objects_from_proc[obj_procid]++;
270 std::map<processor_id_type, std::vector<Point>>
273 std::map<processor_id_type, std::vector<dof_id_type>>
278 for (
auto pair : ghost_objects_from_proc)
281 if (p != comm.
rank())
283 requested_objs_pt[p].reserve(pair.second);
284 requested_objs_id[p].reserve(pair.second);
288 for (Iterator it = range_begin; it != range_end; ++it)
290 DofObjType * obj = *it;
292 if (obj_procid == comm.
rank() ||
297 requested_objs_pt[obj_procid].push_back(p);
298 requested_objs_id[obj_procid].push_back(obj->id());
302 requested_objs_pt_inv;
303 for (
auto & pair : requested_objs_pt)
304 requested_objs_pt_inv[&pair.second] = pair.first;
306 auto gather_functor =
307 [&location_map, &sync]
309 std::vector<typename SyncFunctor::datum> & data)
312 std::size_t query_size = pts.size();
313 std::vector<dof_id_type> query_id(query_size);
314 for (std::size_t i=0; i != query_size; ++i)
319 DofObjType * obj = location_map.
find(pt);
326 query_id[i] = obj->id();
330 sync.gather_data(query_id, data);
333 auto action_functor =
334 [&sync, &requested_objs_id,
335 &requested_objs_pt_inv]
337 const std::vector<typename SyncFunctor::datum> & data)
341 requested_objs_pt_inv[&point_request];
344 sync.act_on_data(requested_objs_id[query_pid], data);
348 typename SyncFunctor::datum * ex =
nullptr;
350 (comm, requested_objs_pt, gather_functor, action_functor, ex);
355 template <
typename Iterator,
356 typename SyncFunctor>
358 const Iterator & range_begin,
359 const Iterator & range_end,
365 template <
typename Iterator,
366 typename DofObjectCheckFunctor,
367 typename SyncFunctor>
369 const Iterator & range_begin,
370 const Iterator & range_end,
371 const DofObjectCheckFunctor & dofobj_check,
375 libmesh_parallel_only(comm);
378 std::map<processor_id_type, dof_id_type>
379 ghost_objects_from_proc;
381 for (Iterator it = range_begin; it != range_end; ++it)
388 if (!dofobj_check(*it))
393 ghost_objects_from_proc[obj_procid]++;
397 std::map<processor_id_type, std::vector<dof_id_type>>
402 for (
auto pair : ghost_objects_from_proc)
405 if (p != comm.
rank())
406 requested_objs_id[p].reserve(pair.second);
409 for (Iterator it = range_begin; it != range_end; ++it)
413 if (!dofobj_check(*it))
417 if (obj_procid == comm.
rank() ||
421 requested_objs_id[obj_procid].push_back(obj->
id());
424 auto gather_functor =
427 std::vector<typename SyncFunctor::datum> & data)
429 sync.gather_data(ids, data);
432 auto action_functor =
435 const std::vector<typename SyncFunctor::datum> & data)
438 sync.act_on_data(ids, data);
442 typename SyncFunctor::datum * ex =
nullptr;
444 (comm, requested_objs_id, gather_functor, action_functor, ex);
450 #ifdef LIBMESH_ENABLE_AMR 451 template <
typename Iterator,
452 typename SyncFunctor>
454 const Iterator & range_begin,
455 const Iterator & range_end,
461 libmesh_parallel_only(comm);
464 std::map<processor_id_type, dof_id_type>
465 ghost_objects_from_proc;
467 for (Iterator it = range_begin; it != range_end; ++it)
471 if (obj_procid == comm.rank() ||
475 if (!parent || !elem->
active())
478 ghost_objects_from_proc[obj_procid]++;
482 std::map<processor_id_type, std::vector<dof_id_type>>
484 std::map<processor_id_type, std::vector<std::pair<dof_id_type,unsigned char>>>
485 requested_objs_parent_id_child_num;
489 for (
auto pair : ghost_objects_from_proc)
492 if (p != comm.rank())
494 requested_objs_id[p].reserve(pair.second);
495 requested_objs_parent_id_child_num[p].reserve(pair.second);
499 for (Iterator it = range_begin; it != range_end; ++it)
503 if (obj_procid == comm.rank() ||
507 if (!parent || !elem->
active())
510 requested_objs_id[obj_procid].push_back(elem->
id());
511 requested_objs_parent_id_child_num[obj_procid].emplace_back
515 std::map<const std::vector<std::pair<dof_id_type,unsigned char>> *,
processor_id_type>
516 requested_objs_parent_id_child_num_inv;
517 for (
auto & pair : requested_objs_parent_id_child_num)
518 requested_objs_parent_id_child_num_inv[&pair.second] = pair.first;
520 auto gather_functor =
523 const std::vector<std::pair<dof_id_type, unsigned char>> & parent_id_child_num,
524 std::vector<typename SyncFunctor::datum> & data)
527 std::size_t query_size = parent_id_child_num.size();
528 std::vector<dof_id_type> query_id(query_size);
529 for (std::size_t i=0; i != query_size; ++i)
531 Elem & parent =
mesh.elem_ref(parent_id_child_num[i].first);
533 Elem * child = parent.
child_ptr(parent_id_child_num[i].second);
536 query_id[i] = child->id();
540 sync.gather_data(query_id, data);
543 auto action_functor =
544 [&sync, &requested_objs_id,
545 &requested_objs_parent_id_child_num_inv]
547 const std::vector<std::pair<dof_id_type, unsigned char>> & parent_id_child_num_request,
548 const std::vector<typename SyncFunctor::datum> & data)
552 requested_objs_parent_id_child_num_inv[&parent_id_child_num_request];
555 sync.act_on_data(requested_objs_id[query_pid], data);
559 typename SyncFunctor::datum * ex =
nullptr;
561 (comm, requested_objs_parent_id_child_num, gather_functor,
565 template <
typename Iterator,
566 typename SyncFunctor>
573 #endif // LIBMESH_ENABLE_AMR 577 template <
typename ElemCheckFunctor,
578 typename NodeCheckFunctor,
579 typename SyncFunctor>
583 const ElemCheckFunctor & elem_check,
584 const NodeCheckFunctor & node_check,
590 std::map<processor_id_type, dof_id_type>
591 ghost_objects_from_proc;
593 for (
const auto & elem :
as_range(range_begin, range_end))
597 if (!elem_check(elem))
603 (proc_id == comm.rank() ||
606 if (elem->active() && i_have_elem)
609 for (
auto n : elem->node_index_range())
611 if (!node_check(elem, n))
615 elem->node_ref(n).processor_id();
617 if (i_have_elem && (node_pid == comm.rank()))
622 libmesh_assert_not_equal_to
624 ghost_objects_from_proc[node_pid]++;
631 ghost_objects_from_proc[request_pid]++;
639 std::map<processor_id_type, std::vector<std::pair<dof_id_type, unsigned char>>>
640 requested_objs_elem_id_node_num;
644 for (
auto pair : ghost_objects_from_proc)
647 if (p != comm.rank())
648 requested_objs_elem_id_node_num[p].reserve(ghost_objects_from_proc[p]);
651 for (
const auto & elem :
as_range(range_begin, range_end))
655 if (!elem_check(elem))
661 (proc_id == comm.rank() ||
664 if (elem->active() && i_have_elem)
669 for (
auto n : elem->node_index_range())
671 if (!node_check(elem, n))
674 const Node & node = elem->node_ref(n);
677 if (i_have_elem && (node_pid == comm.rank()))
682 libmesh_assert_not_equal_to
684 requested_objs_elem_id_node_num[node_pid].emplace_back
685 (elem_id, cast_int<unsigned char>(n));
692 requested_objs_elem_id_node_num[request_pid].emplace_back
693 (elem_id,cast_int<unsigned char>(n));
698 auto gather_functor =
701 const std::vector<std::pair<dof_id_type, unsigned char>> & elem_id_node_num,
702 std::vector<typename SyncFunctor::datum> & data)
705 std::size_t request_size = elem_id_node_num.size();
706 std::vector<dof_id_type> query_id(request_size);
707 for (std::size_t i=0; i != request_size; ++i)
712 const Elem * elem =
mesh.query_elem_ptr(elem_id_node_num[i].first);
716 const unsigned int n = elem_id_node_num[i].second;
717 libmesh_assert_less (n, elem->
n_nodes());
725 query_id[i] = node.
id();
732 sync.gather_data(query_id, data);
735 bool data_changed =
false;
737 auto action_functor =
738 [&sync, &
mesh, &data_changed]
740 const std::vector<std::pair<dof_id_type, unsigned char>> & elem_id_node_num,
741 const std::vector<typename SyncFunctor::datum> & data)
743 const std::size_t data_size = data.size();
745 libmesh_assert_equal_to(elem_id_node_num.size(), data_size);
747 std::vector<dof_id_type> requested_objs_id(data.size());
751 const Elem & elem =
mesh.elem_ref(elem_id_node_num[i].first);
752 const Node & node = elem.
node_ref(elem_id_node_num[i].second);
753 requested_objs_id[i] = node.
id();
760 if (sync.act_on_data(requested_objs_id, data))
765 typename SyncFunctor::datum * ex =
nullptr;
767 (comm, requested_objs_elem_id_node_num, gather_functor,
770 comm.max(data_changed);
777 template <
typename ElemCheckFunctor,
778 typename NodeCheckFunctor,
779 typename SyncFunctor>
783 const ElemCheckFunctor & elem_check,
784 const NodeCheckFunctor & node_check,
788 libmesh_parallel_only(
mesh.comm());
790 bool need_sync =
false;
796 (
mesh, range_begin, range_end, elem_check, node_check,
822 void gather_data (
const std::vector<dof_id_type> & ids, std::vector<datum> & data)
const;
826 void act_on_data (
const std::vector<dof_id_type> & ids,
const std::vector<datum> & data)
const;
847 void gather_data (
const std::vector<dof_id_type> & ids, std::vector<datum> & data)
const;
851 void act_on_data (
const std::vector<dof_id_type> & ids,
const std::vector<datum> & data)
const;
873 void gather_data(
const std::vector<dof_id_type> & ids, std::vector<datum> & data)
const;
877 void act_on_data(
const std::vector<dof_id_type> & ids,
const std::vector<datum> & data)
const;
885 #endif // LIBMESH_PARALLEL_GHOST_SYNC_H T * find(const Point &, const Real tol=TOLERANCE)
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
const Elem * parent() const
A Node is like a Point, but with more information.
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
The definition of the const_element_iterator struct.
This is the base class from which all geometric element types are derived.
processor_id_type rank() const
Point point_of(const T &) const
The libMesh namespace provides an interface to certain functionality in the library.
void act_on_data(const std::vector< dof_id_type > &ids, const std::vector< datum > &data) const
void sync_dofobject_data_by_xyz(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, LocationMap< DofObjType > &location_map, SyncFunctor &sync)
Request data about a range of ghost nodes uniquely identified by their xyz location or a range of act...
bool operator()(const DofObject *) const
uint8_t processor_id_type
This is the MeshBase class.
SyncSubdomainIds(MeshBase &m)
uint8_t processor_id_type
void act_on_data(const std::vector< dof_id_type > &ids, const std::vector< datum > &data) const
const Node & node_ref(const unsigned int i) const
virtual unsigned int n_nodes() const =0
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
void sync_node_data_by_element_id(MeshBase &mesh, const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, const ElemCheckFunctor &elem_check, const NodeCheckFunctor &node_check, SyncFunctor &sync)
Synchronize data about a range of ghost nodes uniquely identified by an element id and local node id...
void act_on_data(const std::vector< dof_id_type > &ids, const std::vector< datum > &data) const
SyncElementIntegers(MeshBase &m, const std::string &integer_name)
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
void gather_data(const std::vector< dof_id_type > &ids, std::vector< datum > &data) const
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
Data structures that enable location-based lookups The key is a hash of the Point location...
unsigned int which_child_am_i(const Elem *e) const
void max(const T &r, T &o, Request &req) const
bool sync_node_data_by_element_id_once(MeshBase &mesh, const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, const ElemCheckFunctor &elem_check, const NodeCheckFunctor &node_check, SyncFunctor &sync)
Synchronize data about a range of ghost nodes uniquely identified by an element id and local node id...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
void gather_data(const std::vector< dof_id_type > &ids, std::vector< datum > &data) const
SyncNodalPositions(MeshBase &m)
processor_id_type processor_id() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
bool has_children() const
void gather_data(const std::vector< dof_id_type > &ids, std::vector< datum > &data) const
void sync_element_data_by_parent_id(MeshBase &mesh, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost elements uniquely identified by their parent id and which child t...
const Elem * child_ptr(unsigned int i) const