libMesh
parallel_ghost_sync.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_PARALLEL_GHOST_SYNC_H
21 #define LIBMESH_PARALLEL_GHOST_SYNC_H
22 
23 // libMesh includes
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"
29 
30 // TIMPI includes
31 #include "timpi/communicator.h"
32 #include "timpi/parallel_sync.h"
33 
34 
35 namespace libMesh
36 {
37 
38 
39 
40 //--------------------------------------------------------------------------
41 namespace Parallel {
42 
43 //------------------------------------------------------------------------
60 template <typename Iterator,
61  typename DofObjType,
62  typename SyncFunctor>
63 void sync_dofobject_data_by_xyz(const Communicator & comm,
64  const Iterator & range_begin,
65  const Iterator & range_end,
66  LocationMap<DofObjType> * location_map,
67  SyncFunctor & sync);
68 
69 //------------------------------------------------------------------------
82 template <typename Iterator,
83  typename SyncFunctor>
84 void sync_dofobject_data_by_id(const Communicator & comm,
85  const Iterator & range_begin,
86  const Iterator & range_end,
87  SyncFunctor & sync);
88 
96 template <typename Iterator,
97  typename DofObjectCheckFunctor,
98  typename SyncFunctor>
99 void sync_dofobject_data_by_id(const Communicator & comm,
100  const Iterator & range_begin,
101  const Iterator & range_end,
102  const DofObjectCheckFunctor & dofobj_check,
103  SyncFunctor & sync);
104 
105 //------------------------------------------------------------------------
119 template <typename Iterator,
120  typename SyncFunctor>
121 void sync_element_data_by_parent_id(MeshBase & mesh,
122  const Iterator & range_begin,
123  const Iterator & range_end,
124  SyncFunctor & sync);
125 
126 //------------------------------------------------------------------------
156 template <typename ElemCheckFunctor,
157  typename NodeCheckFunctor,
158  typename SyncFunctor>
160  const MeshBase::const_element_iterator & range_begin,
161  const MeshBase::const_element_iterator & range_end,
162  const ElemCheckFunctor & elem_check,
163  const NodeCheckFunctor & node_check,
164  SyncFunctor & sync);
165 
166 
167 
168 //------------------------------------------------------------------------
203 template <typename ElemCheckFunctor,
204  typename NodeCheckFunctor,
205  typename SyncFunctor>
206 void sync_node_data_by_element_id(MeshBase & mesh,
207  const MeshBase::const_element_iterator & range_begin,
208  const MeshBase::const_element_iterator & range_end,
209  const ElemCheckFunctor & elem_check,
210  const NodeCheckFunctor & node_check,
211  SyncFunctor & sync);
212 
213 
214 //------------------------------------------------------------------------
215 // Parallel members
216 
217 
218 // "Check" Functor to perform sync operations with no exclusions
220 {
222 
223  bool operator() (const DofObject *) const { return true; }
224 
225  bool operator() (const Elem *, unsigned int) const
226  { return true; }
227 };
228 
229 
230 
231 template <typename Iterator,
232  typename DofObjType,
233  typename SyncFunctor>
234 void sync_dofobject_data_by_xyz(const Communicator & comm,
235  const Iterator & range_begin,
236  const Iterator & range_end,
237  LocationMap<DofObjType> & location_map,
238  SyncFunctor & sync)
239 {
240  // This function must be run on all processors at once
241  libmesh_parallel_only(comm);
242 
243  // We need a valid location_map
244 #ifdef DEBUG
245  bool need_map_update = (range_begin != range_end && location_map.empty());
246  comm.max(need_map_update);
247  libmesh_assert(!need_map_update);
248 #endif
249 
250  // Count the objects to ask each processor about
251  std::vector<dof_id_type>
252  ghost_objects_from_proc(comm.size(), 0);
253 
254  for (Iterator it = range_begin; it != range_end; ++it)
255  {
256  DofObjType * obj = *it;
257  libmesh_assert (obj);
258  processor_id_type obj_procid = obj->processor_id();
259  if (obj_procid != DofObject::invalid_processor_id)
260  ghost_objects_from_proc[obj_procid]++;
261  }
262 
263  // Request sets to send to each processor
264  std::map<processor_id_type, std::vector<Point>>
265  requested_objs_pt;
266  // Corresponding ids to keep track of
267  std::map<processor_id_type, std::vector<dof_id_type>>
268  requested_objs_id;
269 
270  // We know how many objects live on each processor, so reserve()
271  // space for each.
272  for (auto p : IntRange<processor_id_type>(0, comm.size()))
273  if (p != comm.rank() && ghost_objects_from_proc[p])
274  {
275  requested_objs_pt[p].reserve(ghost_objects_from_proc[p]);
276  requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
277  }
278 
279  for (Iterator it = range_begin; it != range_end; ++it)
280  {
281  DofObjType * obj = *it;
282  processor_id_type obj_procid = obj->processor_id();
283  if (obj_procid == comm.rank() ||
284  obj_procid == DofObject::invalid_processor_id)
285  continue;
286 
287  Point p = location_map.point_of(*obj);
288  requested_objs_pt[obj_procid].push_back(p);
289  requested_objs_id[obj_procid].push_back(obj->id());
290  }
291 
292  auto gather_functor =
293  [&location_map, &sync]
294  (processor_id_type /*pid*/, const std::vector<Point> & pts,
295  std::vector<typename SyncFunctor::datum> & data)
296  {
297  // Find the local id of each requested object
298  std::size_t query_size = pts.size();
299  std::vector<dof_id_type> query_id(query_size);
300  for (std::size_t i=0; i != query_size; ++i)
301  {
302  Point pt = pts[i];
303 
304  // Look for this object in the multimap
305  DofObjType * obj = location_map.find(pt);
306 
307  // We'd better find every object we're asked for
308  libmesh_assert (obj);
309 
310  // Return the object's correct processor id,
311  // and our (correct if it's local) id for it.
312  query_id[i] = obj->id();
313  }
314 
315  // Gather whatever data the user wants
316  sync.gather_data(query_id, data);
317  };
318 
319  auto action_functor =
320  [&sync, &requested_objs_id]
321  (processor_id_type pid, const std::vector<Point> &,
322  const std::vector<typename SyncFunctor::datum> & data)
323  {
324  // Let the user process the results
325  sync.act_on_data(requested_objs_id[pid], data);
326  };
327 
328  // Trade requests with other processors
329  typename SyncFunctor::datum * ex = nullptr;
330  pull_parallel_vector_data
331  (comm, requested_objs_pt, gather_functor, action_functor, ex);
332 }
333 
334 
335 
336 template <typename Iterator,
337  typename SyncFunctor>
338 void sync_dofobject_data_by_id(const Communicator & comm,
339  const Iterator & range_begin,
340  const Iterator & range_end,
341  SyncFunctor & sync)
342 {
343  sync_dofobject_data_by_id(comm, range_begin, range_end, SyncEverything(), sync);
344 }
345 
346 template <typename Iterator,
347  typename DofObjectCheckFunctor,
348  typename SyncFunctor>
349 void sync_dofobject_data_by_id(const Communicator & comm,
350  const Iterator & range_begin,
351  const Iterator & range_end,
352  const DofObjectCheckFunctor & dofobj_check,
353  SyncFunctor & sync)
354 {
355  // This function must be run on all processors at once
356  libmesh_parallel_only(comm);
357 
358  // Count the objects to ask each processor about
359  std::vector<dof_id_type>
360  ghost_objects_from_proc(comm.size(), 0);
361 
362  for (Iterator it = range_begin; it != range_end; ++it)
363  {
364  DofObject * obj = *it;
365  libmesh_assert (obj);
366 
367  // We may want to pass Elem* or Node* to the check function, not
368  // just DofObject*
369  if (!dofobj_check(*it))
370  continue;
371 
372  processor_id_type obj_procid = obj->processor_id();
373  if (obj_procid != DofObject::invalid_processor_id)
374  ghost_objects_from_proc[obj_procid]++;
375  }
376 
377  // Request sets to send to each processor
378  std::map<processor_id_type, std::vector<dof_id_type>>
379  requested_objs_id;
380 
381  // We know how many objects live on each processor, so reserve()
382  // space for each.
383  for (auto p : IntRange<processor_id_type>(0, comm.size()))
384  if (p != comm.rank() && ghost_objects_from_proc[p])
385  requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
386 
387  for (Iterator it = range_begin; it != range_end; ++it)
388  {
389  DofObject * obj = *it;
390 
391  if (!dofobj_check(*it))
392  continue;
393 
394  processor_id_type obj_procid = obj->processor_id();
395  if (obj_procid == comm.rank() ||
396  obj_procid == DofObject::invalid_processor_id)
397  continue;
398 
399  requested_objs_id[obj_procid].push_back(obj->id());
400  }
401 
402  auto gather_functor =
403  [&sync]
404  (processor_id_type, const std::vector<dof_id_type> & ids,
405  std::vector<typename SyncFunctor::datum> & data)
406  {
407  sync.gather_data(ids, data);
408  };
409 
410  auto action_functor =
411  [&sync]
412  (processor_id_type, const std::vector<dof_id_type> & ids,
413  const std::vector<typename SyncFunctor::datum> & data)
414  {
415  // Let the user process the results
416  sync.act_on_data(ids, data);
417  };
418 
419  // Trade requests with other processors
420  typename SyncFunctor::datum * ex = nullptr;
421  pull_parallel_vector_data
422  (comm, requested_objs_id, gather_functor, action_functor, ex);
423 }
424 
425 
426 
427 // If there's no refined elements, there's nothing to sync
428 #ifdef LIBMESH_ENABLE_AMR
429 template <typename Iterator,
430  typename SyncFunctor>
432  const Iterator & range_begin,
433  const Iterator & range_end,
434  SyncFunctor & sync)
435 {
436  const Communicator & comm (mesh.comm());
437 
438  // This function must be run on all processors at once
439  libmesh_parallel_only(comm);
440 
441  // Count the objects to ask each processor about
442  std::vector<dof_id_type>
443  ghost_objects_from_proc(comm.size(), 0);
444 
445  for (Iterator it = range_begin; it != range_end; ++it)
446  {
447  Elem * elem = *it;
448  processor_id_type obj_procid = elem->processor_id();
449  if (obj_procid == comm.rank() ||
450  obj_procid == DofObject::invalid_processor_id)
451  continue;
452  const Elem * parent = elem->parent();
453  if (!parent || !elem->active())
454  continue;
455 
456  ghost_objects_from_proc[obj_procid]++;
457  }
458 
459  // Request sets to send to each processor
460  std::map<processor_id_type, std::vector<dof_id_type>>
461  requested_objs_id;
462  std::map<processor_id_type, std::vector<std::pair<dof_id_type,unsigned char>>>
463  requested_objs_parent_id_child_num;
464 
465  // We know how many objects live on each processor, so reserve()
466  // space for each.
467  for (auto p : IntRange<processor_id_type>(0, comm.size()))
468  if (p != comm.rank() && ghost_objects_from_proc[p])
469  {
470  requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
471  requested_objs_parent_id_child_num[p].reserve(ghost_objects_from_proc[p]);
472  }
473 
474  for (Iterator it = range_begin; it != range_end; ++it)
475  {
476  Elem * elem = *it;
477  processor_id_type obj_procid = elem->processor_id();
478  if (obj_procid == comm.rank() ||
479  obj_procid == DofObject::invalid_processor_id)
480  continue;
481  const Elem * parent = elem->parent();
482  if (!parent || !elem->active())
483  continue;
484 
485  requested_objs_id[obj_procid].push_back(elem->id());
486  requested_objs_parent_id_child_num[obj_procid].push_back
487  (std::make_pair
488  (parent->id(),
489  cast_int<unsigned char>
490  (parent->which_child_am_i(elem))));
491  }
492 
493  auto gather_functor =
494  [&mesh, &sync]
496  const std::vector<std::pair<dof_id_type, unsigned char>> & parent_id_child_num,
497  std::vector<typename SyncFunctor::datum> & data)
498  {
499  // Find the id of each requested element
500  std::size_t query_size = parent_id_child_num.size();
501  std::vector<dof_id_type> query_id(query_size);
502  for (std::size_t i=0; i != query_size; ++i)
503  {
504  Elem & parent = mesh.elem_ref(parent_id_child_num[i].first);
505  libmesh_assert(parent.has_children());
506  Elem * child = parent.child_ptr(parent_id_child_num[i].second);
507  libmesh_assert(child);
508  libmesh_assert(child->active());
509  query_id[i] = child->id();
510  }
511 
512  // Gather whatever data the user wants
513  sync.gather_data(query_id, data);
514  };
515 
516  auto action_functor =
517  [&sync, &requested_objs_id]
518  (processor_id_type pid,
519  const std::vector<std::pair<dof_id_type, unsigned char>> &,
520  const std::vector<typename SyncFunctor::datum> & data)
521  {
522  // Let the user process the results
523  sync.act_on_data(requested_objs_id[pid], data);
524  };
525 
526  // Trade requests with other processors
527  typename SyncFunctor::datum * ex = nullptr;
528  pull_parallel_vector_data
529  (comm, requested_objs_parent_id_child_num, gather_functor,
530  action_functor, ex);
531 }
532 #else
533 template <typename Iterator,
534  typename SyncFunctor>
536  const Iterator &,
537  const Iterator &,
538  SyncFunctor &)
539 {
540 }
541 #endif // LIBMESH_ENABLE_AMR
542 
543 
544 
545 template <typename ElemCheckFunctor,
546  typename NodeCheckFunctor,
547  typename SyncFunctor>
549  const MeshBase::const_element_iterator & range_begin,
550  const MeshBase::const_element_iterator & range_end,
551  const ElemCheckFunctor & elem_check,
552  const NodeCheckFunctor & node_check,
553  SyncFunctor & sync)
554 {
555  const Communicator & comm (mesh.comm());
556 
557  // Count the objects to ask each processor about
558  std::vector<dof_id_type>
559  ghost_objects_from_proc(comm.size(), 0);
560 
561  for (const auto & elem : as_range(range_begin, range_end))
562  {
563  libmesh_assert (elem);
564 
565  if (!elem_check(elem))
566  continue;
567 
568  const processor_id_type proc_id = elem->processor_id();
569 
570  bool i_have_elem =
571  (proc_id == comm.rank() ||
573 
574  if (elem->active() && i_have_elem)
575  continue;
576 
577  for (auto n : elem->node_index_range())
578  {
579  if (!node_check(elem, n))
580  continue;
581 
582  const processor_id_type node_pid =
583  elem->node_ref(n).processor_id();
584 
585  if (i_have_elem && (node_pid == comm.rank()))
586  continue;
587 
588  if (i_have_elem)
589  {
590  libmesh_assert_not_equal_to
592  ghost_objects_from_proc[node_pid]++;
593  }
594  else
595  {
596  const processor_id_type request_pid =
597  (node_pid == DofObject::invalid_processor_id) ?
598  proc_id : node_pid;
599  ghost_objects_from_proc[request_pid]++;
600  }
601  }
602  }
603 
604  // Now repeat that iteration, filling request sets this time.
605 
606  // Request sets to send to each processor
607  std::map<processor_id_type, std::vector<std::pair<dof_id_type, unsigned char>>>
608  requested_objs_elem_id_node_num;
609 
610  // We know how many objects live on each processor, so reserve()
611  // space for each.
612  for (auto p : IntRange<processor_id_type>(0, comm.size()))
613  if (p != comm.rank() && ghost_objects_from_proc[p])
614  {
615  requested_objs_elem_id_node_num[p].reserve(ghost_objects_from_proc[p]);
616  }
617 
618  for (const auto & elem : as_range(range_begin, range_end))
619  {
620  libmesh_assert (elem);
621 
622  if (!elem_check(elem))
623  continue;
624 
625  const processor_id_type proc_id = elem->processor_id();
626 
627  bool i_have_elem =
628  (proc_id == comm.rank() ||
630 
631  if (elem->active() && i_have_elem)
632  continue;
633 
634  const dof_id_type elem_id = elem->id();
635 
636  for (auto n : elem->node_index_range())
637  {
638  if (!node_check(elem, n))
639  continue;
640 
641  const Node & node = elem->node_ref(n);
642  const processor_id_type node_pid = node.processor_id();
643 
644  if (i_have_elem && (node_pid == comm.rank()))
645  continue;
646 
647  if (i_have_elem)
648  {
649  libmesh_assert_not_equal_to
651  requested_objs_elem_id_node_num[node_pid].push_back
652  (std::make_pair
653  (elem_id,
654  cast_int<unsigned char>(n)));
655  }
656  else
657  {
658  const processor_id_type request_pid =
659  (node_pid == DofObject::invalid_processor_id) ?
660  proc_id : node_pid;
661  requested_objs_elem_id_node_num[request_pid].push_back
662  (std::make_pair
663  (elem_id,
664  cast_int<unsigned char>(n)));
665  }
666  }
667  }
668 
669  auto gather_functor =
670  [&mesh, &sync]
672  const std::vector<std::pair<dof_id_type, unsigned char>> & elem_id_node_num,
673  std::vector<typename SyncFunctor::datum> & data)
674  {
675  // Find the id of each requested element
676  std::size_t request_size = elem_id_node_num.size();
677  std::vector<dof_id_type> query_id(request_size);
678  for (std::size_t i=0; i != request_size; ++i)
679  {
680  // We might now get queries about remote elements, in which
681  // case we'll have to ignore them and wait for the query
682  // answer to filter to the querier via another source.
683  const Elem * elem = mesh.query_elem_ptr(elem_id_node_num[i].first);
684 
685  if (elem)
686  {
687  const unsigned int n = elem_id_node_num[i].second;
688  libmesh_assert_less (n, elem->n_nodes());
689 
690  const Node & node = elem->node_ref(n);
691 
692  // This isn't a safe assertion in the case where we're
693  // syncing processor ids
694  // libmesh_assert_equal_to (node->processor_id(), comm.rank());
695 
696  query_id[i] = node.id();
697  }
698  else
699  query_id[i] = DofObject::invalid_id;
700  }
701 
702  // Gather whatever data the user wants
703  sync.gather_data(query_id, data);
704  };
705 
706  bool data_changed = false;
707 
708  auto action_functor =
709  [&sync, &mesh, &requested_objs_elem_id_node_num, &data_changed]
710  (processor_id_type pid,
711  const std::vector<std::pair<dof_id_type, unsigned char>> &,
712  const std::vector<typename SyncFunctor::datum> & data)
713  {
714  const auto & elem_id_node_num =
715  requested_objs_elem_id_node_num[pid];
716 
717  const std::size_t data_size = data.size();
718 
719  libmesh_assert_equal_to(elem_id_node_num.size(), data_size);
720 
721  std::vector<dof_id_type> requested_objs_id(data.size());
722 
723  for (auto i : IntRange<std::size_t>(0,data_size))
724  {
725  const Elem & elem = mesh.elem_ref(elem_id_node_num[i].first);
726  const Node & node = elem.node_ref(elem_id_node_num[i].second);
727  requested_objs_id[i] = node.id();
728  }
729 
730  // Let the user process the results. If any of the results
731  // were different than what the user expected, then we may
732  // need to sync again just in case this processor has to
733  // pass on the changes to yet another processor.
734  if (sync.act_on_data(requested_objs_id, data))
735  data_changed = true;
736  };
737 
738  // Trade requests with other processors
739  typename SyncFunctor::datum * ex = nullptr;
740  pull_parallel_vector_data
741  (comm, requested_objs_elem_id_node_num, gather_functor,
742  action_functor, ex);
743 
744  comm.max(data_changed);
745 
746  return data_changed;
747 }
748 
749 
750 
751 template <typename ElemCheckFunctor,
752  typename NodeCheckFunctor,
753  typename SyncFunctor>
755  const MeshBase::const_element_iterator & range_begin,
756  const MeshBase::const_element_iterator & range_end,
757  const ElemCheckFunctor & elem_check,
758  const NodeCheckFunctor & node_check,
759  SyncFunctor & sync)
760 {
761  // This function must be run on all processors at once
762  libmesh_parallel_only(mesh.comm());
763 
764  bool need_sync = false;
765 
766  do
767  {
768  need_sync =
770  (mesh, range_begin, range_end, elem_check, node_check,
771  sync);
772  } while (need_sync);
773 }
774 
775 
776 }
777 
778 
779 
780 // This struct can be created and passed to the
781 // Parallel::sync_dofobject_data_by_id() function.
783 {
784  // The constructor. You need a reference to the mesh where you will
785  // be setting/getting nodal positions.
786  explicit
788 
789  // The datum typedef is required of this functor, so that the
790  // Parallel::sync_dofobject_data_by_id() function can create e.g.
791  // std::vector<datum>.
792  typedef Point datum;
793 
794  // First required interface. This function must fill up the data vector for the
795  // ids specified in the ids vector.
796  void gather_data (const std::vector<dof_id_type> & ids, std::vector<datum> & data) const;
797 
798  // Second required interface. This function must do something with the data in
799  // the data vector for the ids in the ids vector.
800  void act_on_data (const std::vector<dof_id_type> & ids, const std::vector<datum> & data) const;
801 
803 };
804 
805 
806 } // namespace libMesh
807 
808 #endif // LIBMESH_PARALLEL_GHOST_SYNC_H
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Elem::child_ptr
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2567
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::SyncNodalPositions::mesh
MeshBase & mesh
Definition: parallel_ghost_sync.h:802
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::LocationMap
Data structures that enable location-based lookups The key is a hash of the Point location.
Definition: location_maps.h:53
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::Elem::active
bool active() const
Definition: elem.h:2345
parallel_sync.h
libMesh::DofObject
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:53
libMesh::TypeVector::size
auto size() const -> decltype(std::norm(T()))
Definition: type_vector.h:944
libMesh::Parallel::sync_dofobject_data_by_xyz
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...
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::Parallel::sync_node_data_by_element_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)
Synchronize data about a range of ghost nodes uniquely identified by an element id and local node id,...
Definition: parallel_ghost_sync.h:754
libMesh::LocationMap::find
T * find(const Point &, const Real tol=TOLERANCE)
Definition: location_maps.C:112
libMesh::LocationMap::empty
bool empty() const
Definition: location_maps.h:63
libMesh::DofObject::invalid_id
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:421
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::SyncNodalPositions::datum
Point datum
Definition: parallel_ghost_sync.h:792
libMesh::SyncNodalPositions::act_on_data
void act_on_data(const std::vector< dof_id_type > &ids, const std::vector< datum > &data) const
Definition: parallel_ghost_sync.C:51
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::SyncNodalPositions
Definition: parallel_ghost_sync.h:782
libMesh::MeshBase::const_element_iterator
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1891
libMesh::LocationMap::point_of
Point point_of(const T &) const
libMesh::Elem::parent
const Elem * parent() const
Definition: elem.h:2434
libMesh::SyncNodalPositions::gather_data
void gather_data(const std::vector< dof_id_type > &ids, std::vector< datum > &data) const
Definition: parallel_ghost_sync.C:32
libMesh::Parallel::sync_dofobject_data_by_id
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.
Definition: parallel_ghost_sync.h:338
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::Elem::has_children
bool has_children() const
Definition: elem.h:2383
libMesh::SyncNodalPositions::SyncNodalPositions
SyncNodalPositions(MeshBase &m)
Definition: parallel_ghost_sync.C:26
libMesh::Parallel::SyncEverything::operator()
bool operator()(const DofObject *) const
Definition: parallel_ghost_sync.h:223
libMesh::DofObject::invalid_processor_id
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:432
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
data
IterBase * data
Ideally this private member data should have protected access.
Definition: variant_filter_iterator.h:337
libMesh::Parallel::sync_element_data_by_parent_id
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...
Definition: parallel_ghost_sync.h:431
libMesh::Parallel::sync_node_data_by_element_id_once
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,...
Definition: parallel_ghost_sync.h:548
libMesh::Parallel::SyncEverything
Definition: parallel_ghost_sync.h:219
libMesh::Parallel::SyncEverything::SyncEverything
SyncEverything()
Definition: parallel_ghost_sync.h:221
libMesh::Elem::node_ref
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2031
communicator.h
libMesh::Elem::which_child_am_i
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2596