libMesh
sparsity_pattern.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 #ifndef LIBMESH_SPARSITY_PATTERN_H
20 #define LIBMESH_SPARSITY_PATTERN_H
21 
22 // Local Includes
23 #include "libmesh/elem_range.h"
24 #include "libmesh/threads_allocators.h"
25 #include "libmesh/parallel_object.h"
26 
27 // C++ includes
28 #include <vector>
29 #include <unordered_set>
30 
31 namespace libMesh
32 {
33 
34 // Forward declarations
35 class MeshBase;
36 class DofMap;
37 class CouplingMatrix;
38 
49 namespace SparsityPattern // use a namespace so member classes can be forward-declared.
50 {
51 typedef std::vector<dof_id_type, Threads::scalable_allocator<dof_id_type>> Row;
52 class Graph : public std::vector<Row> {};
53 
54 class NonlocalGraph : public std::map<dof_id_type, Row> {};
55 
65 template<typename BidirectionalIterator>
66 static void sort_row (const BidirectionalIterator begin,
67  BidirectionalIterator middle,
68  const BidirectionalIterator end);
69 
81 class Build : public ParallelObject
82 {
83 private:
84  const MeshBase & mesh;
85  const DofMap & dof_map;
87  const std::set<GhostingFunctor *> & coupling_functors;
90 
91  // If there are "spider" nodes in the mesh (i.e. a single node which
92  // is connected to many 1D elements) and Constraints, we can end up
93  // sorting the same set of DOFs multiple times in handle_vi_vj(),
94  // only to find that it has no net effect on the final sparsity. In
95  // such cases it is much faster to keep track of (element_dofs_i,
96  // element_dofs_j) pairs which have already been handled and not
97  // repeat the computation. We use this data structure to keep track
98  // of hashes of sets of dofs we have already seen, thus avoiding
99  // unnecessary caluclations.
100  std::unordered_set<dof_id_type> hashed_dof_sets;
101 
102  void handle_vi_vj(const std::vector<dof_id_type> & element_dofs_i,
103  const std::vector<dof_id_type> & element_dofs_j);
104 
105  void sorted_connected_dofs(const Elem * elem,
106  std::vector<dof_id_type> & dofs_vi,
107  unsigned int vi);
108 
109 public:
110 
113 
114  std::vector<dof_id_type> n_nz;
115  std::vector<dof_id_type> n_oz;
116 
117  Build (const MeshBase & mesh_in,
118  const DofMap & dof_map_in,
119  const CouplingMatrix * dof_coupling_in,
120  const std::set<GhostingFunctor *> & coupling_functors_in,
121  const bool implicit_neighbor_dofs_in,
122  const bool need_full_sparsity_pattern_in);
123 
124  Build (Build & other, Threads::split);
125 
126  void operator()(const ConstElemRange & range);
127 
128  void join (const Build & other);
129 
130  void parallel_sync ();
131 };
132 
133 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER)
134 
139 void _dummy_function(void);
140 #endif
141 
142 }
143 
144 
145 
146 // ------------------------------------------------------------
147 // SparsityPattern inline member functions
148 template<typename BidirectionalIterator>
149 inline
150 void SparsityPattern::sort_row (const BidirectionalIterator begin,
151  BidirectionalIterator middle,
152  const BidirectionalIterator end)
153 {
154  if ((begin == middle) || (middle == end)) return;
155 
156  libmesh_assert_greater (std::distance (begin, middle), 0);
157  libmesh_assert_greater (std::distance (middle, end), 0);
158  libmesh_assert (std::unique (begin, middle) == middle);
159  libmesh_assert (std::unique (middle, end) == end);
160 
161  while (middle != end)
162  {
163  BidirectionalIterator
164  b = middle,
165  a = b-1;
166 
167  // Bubble-sort the middle value downward
168  while (!(*a < *b)) // *a & *b are less-than comparable, so use <
169  {
170  std::swap (*a, *b);
171 
172 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER)
173  /* Prohibit optimization at this point since gcc 3.3.5 seems
174  to have a bug. */
176 #endif
177 
178  if (a == begin) break;
179 
180  b=a;
181  --a;
182  }
183 
184  ++middle;
185  }
186 
187  // Assure the algorithm worked if we are in DEBUG mode
188 #ifdef DEBUG
189  {
190  // SGI STL extension!
191  // libmesh_assert (std::is_sorted(begin,end));
192 
193  BidirectionalIterator
194  prev = begin,
195  first = begin;
196 
197  for (++first; first != end; prev=first, ++first)
198  if (*first < *prev)
199  libmesh_assert(false);
200  }
201 #endif
202 
203  // Make sure the two ranges did not contain any common elements
204  libmesh_assert (std::unique (begin, end) == end);
205 }
206 
207 } // namespace libMesh
208 
209 #endif // LIBMESH_SPARSITY_PATTERN_H
libMesh::SparsityPattern::Row
std::vector< dof_id_type, Threads::scalable_allocator< dof_id_type > > Row
Definition: sparsity_pattern.h:51
libMesh::SparsityPattern::Build::sorted_connected_dofs
void sorted_connected_dofs(const Elem *elem, std::vector< dof_id_type > &dofs_vi, unsigned int vi)
Definition: sparsity_pattern.C:90
libMesh::SparsityPattern::_dummy_function
void _dummy_function(void)
Dummy function that does nothing but can be used to prohibit compiler optimization in some situations...
Definition: sparsity_pattern.C:84
libMesh::SparsityPattern::Build::handle_vi_vj
void handle_vi_vj(const std::vector< dof_id_type > &element_dofs_i, const std::vector< dof_id_type > &element_dofs_j)
Definition: sparsity_pattern.C:105
libMesh::SparsityPattern::Build::nonlocal_pattern
SparsityPattern::NonlocalGraph nonlocal_pattern
Definition: sparsity_pattern.h:112
libMesh::SparsityPattern::Build::dof_map
const DofMap & dof_map
Definition: sparsity_pattern.h:85
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::Threads::split
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
Definition: threads_none.h:63
libMesh::SparsityPattern::NonlocalGraph
Definition: sparsity_pattern.h:54
libMesh::SparsityPattern::Build::hashed_dof_sets
std::unordered_set< dof_id_type > hashed_dof_sets
Definition: sparsity_pattern.h:100
libMesh::SparsityPattern::Build::sparsity_pattern
SparsityPattern::Graph sparsity_pattern
Definition: sparsity_pattern.h:111
libMesh::SparsityPattern::sort_row
static void sort_row(const BidirectionalIterator begin, BidirectionalIterator middle, const BidirectionalIterator end)
Splices the two sorted ranges [begin,middle) and [middle,end) into one sorted range [begin,...
libMesh::SparsityPattern::Build::parallel_sync
void parallel_sync()
Definition: sparsity_pattern.C:472
libMesh::SparsityPattern::Build::n_oz
std::vector< dof_id_type > n_oz
Definition: sparsity_pattern.h:115
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::SparsityPattern::Build
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
Definition: sparsity_pattern.h:81
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::SparsityPattern::Build::dof_coupling
const CouplingMatrix * dof_coupling
Definition: sparsity_pattern.h:86
libMesh::SparsityPattern::Build::coupling_functors
const std::set< GhostingFunctor * > & coupling_functors
Definition: sparsity_pattern.h:87
libMesh::SparsityPattern::Build::operator()
void operator()(const ConstElemRange &range)
Definition: sparsity_pattern.C:232
libMesh::SparsityPattern::Build::need_full_sparsity_pattern
const bool need_full_sparsity_pattern
Definition: sparsity_pattern.h:89
distance
Real distance(const Point &p)
Definition: subdomains_ex3.C:50
swap
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
Definition: variant_filter_iterator.h:478
libMesh::SparsityPattern::Build::n_nz
std::vector< dof_id_type > n_nz
Definition: sparsity_pattern.h:114
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::SparsityPattern::Build::Build
Build(const MeshBase &mesh_in, const DofMap &dof_map_in, const CouplingMatrix *dof_coupling_in, const std::set< GhostingFunctor * > &coupling_functors_in, const bool implicit_neighbor_dofs_in, const bool need_full_sparsity_pattern_in)
Definition: sparsity_pattern.C:44
libMesh::StoredRange
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:52
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::MeshTools::Subdivision::prev
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
Definition: mesh_subdivision_support.h:108
libMesh::CouplingMatrix
This class defines a coupling matrix.
Definition: coupling_matrix.h:54
libMesh::SparsityPattern::Build::join
void join(const Build &other)
Definition: sparsity_pattern.C:366
libMesh::ParallelObject
An object whose state is distributed along a set of processors.
Definition: parallel_object.h:55
libMesh::SparsityPattern::Build::implicit_neighbor_dofs
const bool implicit_neighbor_dofs
Definition: sparsity_pattern.h:88
libMesh::SparsityPattern::Graph
Definition: sparsity_pattern.h:52
libMesh::SparsityPattern::Build::mesh
const MeshBase & mesh
Definition: sparsity_pattern.h:84