libMesh
ghost_point_neighbors.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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 // C++ Includes
20 #include <set>
21 #include <utility> // std::make_pair
22 
23 // Local Includes
24 #include "libmesh/ghost_point_neighbors.h"
25 
26 #include "libmesh/elem.h"
27 #include "libmesh/remote_elem.h"
28 
29 namespace libMesh
30 {
31 
32 void GhostPointNeighbors::operator()
33  (const MeshBase::const_element_iterator & range_begin,
34  const MeshBase::const_element_iterator & range_end,
36  GhostPointNeighbors::map_type & coupled_elements)
37 {
38  // Using the connected_nodes set rather than point_neighbors() gives
39  // us correct results even in corner cases, such as where two
40  // elements meet only at a corner. ;-)
41 
42  std::set<const Node *> connected_nodes;
43 
44  // Links between boundary and interior elements on mixed
45  // dimensional meshes also give us correct ghosting in this way.
46  std::set<const Elem *> interior_parents;
47 
48  // We also preserve neighbors and their neighboring children for
49  // active local elements - in most cases this is redundant with the
50  // node check, but for non-conforming Tet4 meshes and
51  // non-level-one-conforming 2D+3D meshes it is possible for an
52  // element and its coarse neighbor to not share any vertices.
53  //
54  // We also preserve interior parents for active pid elements
55 
56 
57  // This code is just for geometric coupling, so we use a null
58  // CouplingMatrix pointer. We'll declare that here so as to avoid
59  // confusing the insert() calls later.
61 
62  for (MeshBase::const_element_iterator elem_it = range_begin;
63  elem_it!=range_end; ++elem_it)
64  {
65  const Elem * elem = *elem_it;
66 
67  if (elem->processor_id() != p)
68  coupled_elements.insert (std::make_pair(elem,nullcm));
69 
70  for (auto neigh : elem->neighbor_ptr_range())
71  {
72  if (neigh && neigh != remote_elem)
73  {
74 #ifdef LIBMESH_ENABLE_AMR
75  if (!neigh->active())
76  {
77  std::vector<const Elem*> family;
78  neigh->active_family_tree_by_neighbor(family, elem);
79 
80  for (std::size_t i=0; i!=family.size(); ++i)
81  if (family[i]->processor_id() != p)
82  coupled_elements.insert
83  (std::make_pair(family[i], nullcm));
84  }
85  else
86 #endif
87  if (neigh->processor_id() != p)
88  coupled_elements.insert
89  (std::make_pair(neigh, nullcm));
90  }
91  }
92 
93  // It is possible that a refined boundary element will not
94  // touch any nodes of its interior_parent, in TRI3/TET4 and in
95  // non-level-one rule cases. So we can't just rely on node
96  // connections to preserve interior_parent(). However, trying
97  // to preserve interior_parent() manually only works if it's on
98  // the same Mesh, which is *not* guaranteed! So we'll
99  // double-check later to make sure our interior parents are in
100  // the mesh before we connect them.
101  if (elem->dim() < LIBMESH_DIM &&
102  elem->interior_parent() &&
103  elem->interior_parent()->processor_id() != p)
104  interior_parents.insert (elem->interior_parent());
105 
106  // Add nodes connected to active local elements
107  for (auto n : elem->node_index_range())
108  connected_nodes.insert (elem->node_ptr(n));
109  }
110 
111  // Connect any interior_parents who are really in our mesh
112  for (const auto & elem : _mesh.element_ptr_range())
113  {
114  std::set<const Elem *>::iterator ip_it =
115  interior_parents.find(elem);
116 
117  if (ip_it != interior_parents.end())
118  {
119  coupled_elements.insert
120  (std::make_pair(elem, nullcm));
121 
122  // Shrink the set ASAP to speed up subsequent searches
123  interior_parents.erase(ip_it);
124  }
125  }
126 
127  // Connect any active elements which are connected to our range's
128  // elements' nodes by addin elements connected to nodes on active
129  // local elements.
130  for (const auto & elem : _mesh.active_element_ptr_range())
131  if (elem->processor_id() != p)
132  for (auto & n : elem->node_ref_range())
133  if (connected_nodes.count(&n))
134  coupled_elements.insert(std::make_pair(elem, nullcm));
135 }
136 
137 } // namespace libMesh
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1494
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2065
const Elem * interior_parent() const
Definition: elem.C:951
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
uint8_t processor_id_type
Definition: id_types.h:99
const class libmesh_nullptr_t libmesh_nullptr
The libMesh namespace provides an interface to certain functionality in the library.
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
std::unordered_map< const Elem *, const CouplingMatrix * > map_type
What elements do we care about and what variables do we care about on each element?
virtual unsigned int dim() const =0
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:2855
void active_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to neighbor...
Definition: elem.C:1984
processor_id_type processor_id()
Definition: libmesh_base.h:96
processor_id_type processor_id() const
Definition: dof_object.h:694
This class defines a coupling matrix.
const RemoteElem * remote_elem
Definition: remote_elem.C:57