libMesh
default_coupling.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 
20 // Local Includes
21 #include "libmesh/default_coupling.h"
22 
23 #include "libmesh/coupling_matrix.h"
24 #include "libmesh/elem.h"
25 #include "libmesh/periodic_boundaries.h"
26 #include "libmesh/remote_elem.h"
27 
28 // C++ Includes
29 #include <unordered_set>
30 
31 namespace libMesh
32 {
33 
35 {
36  // We used to treat an empty 0x0 _dof_coupling matrix as if it
37  // were an NxN all-ones matrix. We'd like to stop supporting this
38  // behavior, but for now we'll just warn about it, while supporting
39  // it via the preferred mechanism: a NULL _dof_coupling
40  // matrix pointer is interpreted as a full coupling matrix.
41  if (dof_coupling && dof_coupling->empty())
42  {
43  libmesh_deprecated();
44  _dof_coupling = NULL;
45  }
46  else
47  _dof_coupling = dof_coupling;
48 }
49 
50 
51 
53 {
54  // Unless we have periodic boundary conditions, we don't need
55  // anything precomputed.
56 #ifdef LIBMESH_ENABLE_PERIODIC
57  if (!_periodic_bcs || _periodic_bcs->empty())
58  return;
59 #endif
60 
61  // If we do have periodic boundary conditions, we'll need a master
62  // point locator, so we'd better have a mesh to build it on.
64 
65  // Make sure an up-to-date master point locator has been
66  // constructed; we'll need to grab sub-locators soon.
68 }
69 
70 
71 
72 void DefaultCoupling::operator()
73  (const MeshBase::const_element_iterator & range_begin,
74  const MeshBase::const_element_iterator & range_end,
76  map_type & coupled_elements)
77 {
78  LOG_SCOPE("operator()", "DefaultCoupling");
79 
80 #ifdef LIBMESH_ENABLE_PERIODIC
81  bool check_periodic_bcs =
82  (_periodic_bcs && !_periodic_bcs->empty());
83 
84  UniquePtr<PointLocatorBase> point_locator;
85  if (check_periodic_bcs)
86  {
88  point_locator = _mesh->sub_point_locator();
89  }
90 #endif
91 
92  if (!this->_n_levels)
93  {
94  for (MeshBase::const_element_iterator elem_it = range_begin;
95  elem_it != range_end; ++elem_it)
96  {
97  const Elem * const elem = *elem_it;
98 
99  if (elem->processor_id() != p)
100  coupled_elements.insert (std::make_pair(elem,_dof_coupling));
101  }
102  return;
103  }
104 
105  typedef std::unordered_set<const Elem*> set_type;
106  set_type next_elements_to_check(range_begin, range_end);
107  set_type elements_to_check;
108  set_type elements_checked;
109 
110  for (unsigned int i=0; i != this->_n_levels; ++i)
111  {
112  elements_to_check.swap(next_elements_to_check);
113  next_elements_to_check.clear();
114  elements_checked.insert(elements_to_check.begin(), elements_to_check.end());
115 
116  for (set_type::const_iterator
117  elem_it = elements_to_check.begin(),
118  elem_end = elements_to_check.end();
119  elem_it != elem_end; ++elem_it)
120  {
121  std::vector<const Elem *> active_neighbors;
122 
123  const Elem * const elem = *elem_it;
124 
125  if (elem->processor_id() != p)
126  coupled_elements.insert (std::make_pair(elem,_dof_coupling));
127 
128  for (auto s : elem->side_index_range())
129  {
130  const Elem * neigh = elem->neighbor_ptr(s);
131 
132  // If we have a neighbor here
133  if (neigh)
134  {
135  // Mesh ghosting might ask us about what we want to
136  // distribute along with non-local elements, and those
137  // non-local elements might have remote neighbors, and
138  // if they do then we can't say anything about them.
139  if (neigh == remote_elem)
140  continue;
141  }
142 #ifdef LIBMESH_ENABLE_PERIODIC
143  // We might still have a periodic neighbor here
144  else if (check_periodic_bcs)
145  {
147 
148  neigh = elem->topological_neighbor
149  (s, *_mesh, *point_locator, _periodic_bcs);
150  }
151 #endif
152 
153  // With no regular *or* periodic neighbors we have nothing
154  // to do.
155  if (!neigh)
156  continue;
157 
158  // With any kind of neighbor, we need to couple to all the
159  // active descendants on our side.
160 #ifdef LIBMESH_ENABLE_AMR
161  if (neigh == elem->neighbor_ptr(s))
162  neigh->active_family_tree_by_neighbor(active_neighbors,elem);
163 # ifdef LIBMESH_ENABLE_PERIODIC
164  else
166  (active_neighbors,elem,*_mesh,*point_locator,_periodic_bcs);
167 # endif
168 #else
169  active_neighbors.clear();
170  active_neighbors.push_back(neigh);
171 #endif
172 
173  for (std::size_t a=0; a != active_neighbors.size(); ++a)
174  {
175  const Elem * neighbor = active_neighbors[a];
176 
177  if (!elements_checked.count(neighbor))
178  next_elements_to_check.insert(neighbor);
179 
180  if (neighbor->processor_id() != p)
181  coupled_elements.insert
182  (std::make_pair(neighbor, _dof_coupling));
183  }
184  }
185  }
186  }
187 }
188 
189 
190 } // namespace libMesh
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1494
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2083
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
void active_family_tree_by_topological_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, const bool reset=true) const
Same as the active_family_tree_by_neighbor() member, but the neighbor here may be a topological (e...
Definition: elem.C:1942
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(j)
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:1967
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1067
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?
void set_dof_coupling(const CouplingMatrix *dof_coupling)
const CouplingMatrix * _dof_coupling
const PeriodicBoundaries * _periodic_bcs
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
UniquePtr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:534
processor_id_type processor_id() const
Definition: dof_object.h:694
virtual void mesh_reinit() libmesh_override
If we have periodic boundaries, then we&#39;ll need the mesh to have an updated point locator whenever we...
This class defines a coupling matrix.
const RemoteElem * remote_elem
Definition: remote_elem.C:57