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
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor. 
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
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject. 
virtual unsigned int n_nodes() const =0
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
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