20 #ifndef LIBMESH_PARALLEL_GHOST_SYNC_H 21 #define LIBMESH_PARALLEL_GHOST_SYNC_H 58 template <
typename Iterator,
62 const Iterator & range_begin,
63 const Iterator & range_end,
64 LocationMap<DofObjType> * location_map,
80 template <
typename Iterator,
83 const Iterator & range_begin,
84 const Iterator & range_end,
94 template <
typename Iterator,
95 typename DofObjectCheckFunctor,
98 const Iterator & range_begin,
99 const Iterator & range_end,
100 const DofObjectCheckFunctor & dofobj_check,
117 template <
typename Iterator,
118 typename SyncFunctor>
120 const Iterator & range_begin,
121 const Iterator & range_end,
154 template <
typename ElemCheckFunctor,
155 typename NodeCheckFunctor,
156 typename SyncFunctor>
158 const MeshBase::const_element_iterator & range_begin,
159 const MeshBase::const_element_iterator & range_end,
160 const ElemCheckFunctor & elem_check,
161 const NodeCheckFunctor & node_check,
201 template <
typename ElemCheckFunctor,
202 typename NodeCheckFunctor,
203 typename SyncFunctor>
205 const MeshBase::const_element_iterator & range_begin,
206 const MeshBase::const_element_iterator & range_end,
207 const ElemCheckFunctor & elem_check,
208 const NodeCheckFunctor & node_check,
229 template <
typename Iterator,
231 typename SyncFunctor>
233 const Iterator & range_begin,
234 const Iterator & range_end,
239 libmesh_parallel_only(comm);
243 bool need_map_update = (range_begin != range_end && location_map.
empty());
244 comm.
max(need_map_update);
245 libmesh_assert(!need_map_update);
249 std::vector<dof_id_type>
250 ghost_objects_from_proc(comm.
size(), 0);
252 for (Iterator it = range_begin; it != range_end; ++it)
254 DofObjType * obj = *it;
255 libmesh_assert (obj);
258 ghost_objects_from_proc[obj_procid]++;
262 std::map<processor_id_type, std::vector<Point>>
265 std::map<processor_id_type, std::vector<dof_id_type>>
271 if (p != comm.
rank() && ghost_objects_from_proc[p])
273 requested_objs_pt[p].reserve(ghost_objects_from_proc[p]);
274 requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
277 for (Iterator it = range_begin; it != range_end; ++it)
279 DofObjType * obj = *it;
281 if (obj_procid == comm.
rank() ||
286 requested_objs_pt[obj_procid].push_back(p);
287 requested_objs_id[obj_procid].push_back(obj->id());
290 auto gather_functor =
291 [&location_map, &sync]
293 std::vector<typename SyncFunctor::datum> &
data)
296 std::size_t query_size = pts.size();
297 std::vector<dof_id_type> query_id(query_size);
298 for (std::size_t i=0; i != query_size; ++i)
303 DofObjType * obj = location_map.
find(pt);
306 libmesh_assert (obj);
310 query_id[i] = obj->id();
314 sync.gather_data(query_id,
data);
317 auto action_functor =
318 [&sync, &requested_objs_id]
320 const std::vector<typename SyncFunctor::datum> &
data)
323 sync.act_on_data(requested_objs_id[pid],
data);
327 typename SyncFunctor::datum * ex =
nullptr;
329 (comm, requested_objs_pt, gather_functor, action_functor, ex);
334 template <
typename Iterator,
335 typename SyncFunctor>
337 const Iterator & range_begin,
338 const Iterator & range_end,
344 template <
typename Iterator,
345 typename DofObjectCheckFunctor,
346 typename SyncFunctor>
348 const Iterator & range_begin,
349 const Iterator & range_end,
350 const DofObjectCheckFunctor & dofobj_check,
354 libmesh_parallel_only(comm);
357 std::vector<dof_id_type>
358 ghost_objects_from_proc(comm.
size(), 0);
360 for (Iterator it = range_begin; it != range_end; ++it)
363 libmesh_assert (obj);
367 if (!dofobj_check(*it))
372 ghost_objects_from_proc[obj_procid]++;
376 std::map<processor_id_type, std::vector<dof_id_type>>
382 if (p != comm.
rank() && ghost_objects_from_proc[p])
383 requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
385 for (Iterator it = range_begin; it != range_end; ++it)
389 if (!dofobj_check(*it))
393 if (obj_procid == comm.
rank() ||
397 requested_objs_id[obj_procid].push_back(obj->
id());
400 auto gather_functor =
403 std::vector<typename SyncFunctor::datum> &
data)
405 sync.gather_data(ids,
data);
408 auto action_functor =
411 const std::vector<typename SyncFunctor::datum> &
data)
414 sync.act_on_data(ids,
data);
418 typename SyncFunctor::datum * ex =
nullptr;
420 (comm, requested_objs_id, gather_functor, action_functor, ex);
426 #ifdef LIBMESH_ENABLE_AMR 427 template <
typename Iterator,
428 typename SyncFunctor>
430 const Iterator & range_begin,
431 const Iterator & range_end,
437 libmesh_parallel_only(comm);
440 std::vector<dof_id_type>
441 ghost_objects_from_proc(comm.size(), 0);
443 for (Iterator it = range_begin; it != range_end; ++it)
447 if (obj_procid == comm.rank() ||
451 if (!parent || !elem->
active())
454 ghost_objects_from_proc[obj_procid]++;
458 std::map<processor_id_type, std::vector<dof_id_type>>
460 std::map<processor_id_type, std::vector<std::pair<dof_id_type,unsigned char>>>
461 requested_objs_parent_id_child_num;
466 if (p != comm.rank() && ghost_objects_from_proc[p])
468 requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
469 requested_objs_parent_id_child_num[p].reserve(ghost_objects_from_proc[p]);
472 for (Iterator it = range_begin; it != range_end; ++it)
476 if (obj_procid == comm.rank() ||
480 if (!parent || !elem->
active())
483 requested_objs_id[obj_procid].push_back(elem->
id());
484 requested_objs_parent_id_child_num[obj_procid].push_back
487 cast_int<unsigned char>
491 auto gather_functor =
494 const std::vector<std::pair<dof_id_type, unsigned char>> & parent_id_child_num,
495 std::vector<typename SyncFunctor::datum> &
data)
498 std::size_t query_size = parent_id_child_num.size();
499 std::vector<dof_id_type> query_id(query_size);
500 for (std::size_t i=0; i != query_size; ++i)
502 Elem & parent =
mesh.elem_ref(parent_id_child_num[i].first);
504 Elem * child = parent.
child_ptr(parent_id_child_num[i].second);
505 libmesh_assert(child);
506 libmesh_assert(child->active());
507 query_id[i] = child->id();
511 sync.gather_data(query_id,
data);
514 auto action_functor =
515 [&sync, &requested_objs_id]
517 const std::vector<std::pair<dof_id_type, unsigned char>> &,
518 const std::vector<typename SyncFunctor::datum> &
data)
521 sync.act_on_data(requested_objs_id[pid],
data);
525 typename SyncFunctor::datum * ex =
nullptr;
527 (comm, requested_objs_parent_id_child_num, gather_functor,
531 template <
typename Iterator,
532 typename SyncFunctor>
539 #endif // LIBMESH_ENABLE_AMR 543 template <
typename ElemCheckFunctor,
544 typename NodeCheckFunctor,
545 typename SyncFunctor>
549 const ElemCheckFunctor & elem_check,
550 const NodeCheckFunctor & node_check,
556 std::vector<dof_id_type>
557 ghost_objects_from_proc(comm.size(), 0);
559 for (
const auto & elem :
as_range(range_begin, range_end))
561 libmesh_assert (elem);
563 if (!elem_check(elem))
569 (proc_id == comm.rank() ||
572 if (elem->active() && i_have_elem)
575 for (
auto n : elem->node_index_range())
577 if (!node_check(elem, n))
581 elem->node_ref(n).processor_id();
583 if (i_have_elem && (node_pid == comm.rank()))
588 libmesh_assert_not_equal_to
590 ghost_objects_from_proc[node_pid]++;
597 ghost_objects_from_proc[request_pid]++;
605 std::map<processor_id_type, std::vector<std::pair<dof_id_type, unsigned char>>>
606 requested_objs_elem_id_node_num;
611 if (p != comm.rank() && ghost_objects_from_proc[p])
613 requested_objs_elem_id_node_num[p].reserve(ghost_objects_from_proc[p]);
616 for (
const auto & elem :
as_range(range_begin, range_end))
618 libmesh_assert (elem);
620 if (!elem_check(elem))
626 (proc_id == comm.rank() ||
629 if (elem->active() && i_have_elem)
634 for (
auto n : elem->node_index_range())
636 if (!node_check(elem, n))
639 const Node & node = elem->node_ref(n);
642 if (i_have_elem && (node_pid == comm.rank()))
647 libmesh_assert_not_equal_to
649 requested_objs_elem_id_node_num[node_pid].push_back
652 cast_int<unsigned char>(n)));
659 requested_objs_elem_id_node_num[request_pid].push_back
662 cast_int<unsigned char>(n)));
667 auto gather_functor =
670 const std::vector<std::pair<dof_id_type, unsigned char>> & elem_id_node_num,
671 std::vector<typename SyncFunctor::datum> &
data)
674 std::size_t request_size = elem_id_node_num.size();
675 std::vector<dof_id_type> query_id(request_size);
676 for (std::size_t i=0; i != request_size; ++i)
681 const Elem * elem =
mesh.query_elem_ptr(elem_id_node_num[i].first);
685 const unsigned int n = elem_id_node_num[i].second;
686 libmesh_assert_less (n, elem->
n_nodes());
694 query_id[i] = node.
id();
701 sync.gather_data(query_id,
data);
704 bool data_changed =
false;
706 auto action_functor =
707 [&sync, &
mesh, &requested_objs_elem_id_node_num, &data_changed]
709 const std::vector<std::pair<dof_id_type, unsigned char>> &,
710 const std::vector<typename SyncFunctor::datum> &
data)
712 const auto & elem_id_node_num =
713 requested_objs_elem_id_node_num[pid];
715 const std::size_t data_size =
data.size();
717 libmesh_assert_equal_to(elem_id_node_num.size(), data_size);
719 std::vector<dof_id_type> requested_objs_id(
data.size());
723 const Elem & elem =
mesh.elem_ref(elem_id_node_num[i].first);
724 const Node & node = elem.
node_ref(elem_id_node_num[i].second);
725 requested_objs_id[i] = node.
id();
732 if (sync.act_on_data(requested_objs_id,
data))
737 typename SyncFunctor::datum * ex =
nullptr;
739 (comm, requested_objs_elem_id_node_num, gather_functor,
742 comm.max(data_changed);
749 template <
typename ElemCheckFunctor,
750 typename NodeCheckFunctor,
751 typename SyncFunctor>
755 const ElemCheckFunctor & elem_check,
756 const NodeCheckFunctor & node_check,
760 libmesh_parallel_only(
mesh.comm());
762 bool need_sync =
false;
768 (
mesh, range_begin, range_end, elem_check, node_check,
794 void gather_data (
const std::vector<dof_id_type> & ids, std::vector<datum> &
data)
const;
798 void act_on_data (
const std::vector<dof_id_type> & ids,
const std::vector<datum> &
data)
const;
806 #endif // LIBMESH_PARALLEL_GHOST_SYNC_H T * find(const Point &, const Real tol=TOLERANCE)
const Elem * parent() const
A geometric point in (x,y,z) space associated with a DOF.
processor_id_type size() const
The base class for all geometric element types.
uint8_t processor_id_type
void sync_dofobject_data_by_xyz(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, LocationMap< DofObjType > *location_map, SyncFunctor &sync)
Point point_of(const T &) const
bool operator()(const DofObject *) const
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
processor_id_type rank() const
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, RequestContainer &reqs, GatherFunctor &gather_data, ActionFunctor &act_on_data, const datum *example)
virtual unsigned int n_nodes() const =0
static const processor_id_type invalid_processor_id
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)
SimpleRange< I > as_range(const std::pair< I, I > &p)
static const dof_id_type invalid_id
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
std::map-like data structure using hashed Points for keys.
unsigned int which_child_am_i(const Elem *e) 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)
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 geometric point in (x,y,z) space.
bool has_children() const
void sync_element_data_by_parent_id(MeshBase &mesh, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
const Elem * child_ptr(unsigned int i) const