libMesh
sparsity_pattern.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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 <algorithm> // is_sorted
29 #include <unordered_set>
30 #include <vector>
31 
32 namespace libMesh
33 {
34 
35 // Forward declarations
36 class DofMap;
37 class CouplingMatrix;
38 class StaticCondensationDofMap;
39 
50 namespace SparsityPattern // use a namespace so member classes can be forward-declared.
51 {
52 typedef std::vector<dof_id_type, Threads::scalable_allocator<dof_id_type>> Row;
53 class Graph : public std::vector<Row> {};
54 
55 class NonlocalGraph : public std::map<dof_id_type, Row> {};
56 
66 template<typename BidirectionalIterator>
67 static void sort_row (const BidirectionalIterator begin,
68  BidirectionalIterator middle,
69  const BidirectionalIterator end);
70 
71 
72 
78  {
79  public:
80  virtual ~AugmentSparsityPattern () = default;
81 
85  virtual void augment_sparsity_pattern (SparsityPattern::Graph & sparsity,
86  std::vector<dof_id_type> & n_nz,
87  std::vector<dof_id_type> & n_oz) = 0;
88  };
89 
90 
91 
103 class Build : public ParallelObject
104 {
105 public:
106  Build (const DofMap & dof_map_in,
107  const CouplingMatrix * dof_coupling_in,
108  const std::set<GhostingFunctor *> & coupling_functors_in,
109  const bool implicit_neighbor_dofs_in,
110  const bool need_full_sparsity_pattern_in,
111  const bool calculate_constrained_in = false,
112  const StaticCondensationDofMap * sc = nullptr);
113 
119  Build (const Build &) = default;
120  Build & operator= (const Build &) = delete;
121  Build (Build &&) = default;
122  Build & operator= (Build &&) = delete;
123  ~Build () = default;
124 
128  Build (Build & other, Threads::split);
129 
134  void operator()(const ConstElemRange & range);
135 
140  void join (const Build & other);
141 
146  void parallel_sync ();
147 
153  { return sparsity_pattern; }
154 
161  { return nonlocal_pattern; }
162 
166  std::size_t n_nonzeros() const;
167 
172  const std::vector<dof_id_type> & get_n_nz() const
173  { return n_nz; }
174 
179  const std::vector<dof_id_type> & get_n_oz() const
180  { return n_oz; }
181 
187 
192  std::vector<dof_id_type> & n_nz,
193  std::vector<dof_id_type> & n_oz,
194  void * context),
195  void * context)
196  { func(sparsity_pattern, n_nz, n_oz, context); }
197 
203  {
204  sparsity_pattern.clear();
205  nonlocal_pattern.clear();
206  }
207 
208 private:
209  const DofMap & dof_map;
211  const std::set<GhostingFunctor *> & coupling_functors;
216 
228  std::unordered_set<dof_id_type> hashed_dof_sets;
229 
231  std::vector<dof_id_type> dummy_vec;
232 
233  void handle_vi_vj(const std::vector<dof_id_type> & element_dofs_i,
234  const std::vector<dof_id_type> & element_dofs_j);
235 
236  void sorted_connected_dofs(const Elem * elem,
237  std::vector<dof_id_type> & dofs_vi,
238  unsigned int vi);
239 
240 #ifndef LIBMESH_ENABLE_DEPRECATED
241 private:
242 #endif
243 
245 
247 
248  std::vector<dof_id_type> n_nz;
249 
250  std::vector<dof_id_type> n_oz;
251 };
252 
253 }
254 
255 
256 
257 // ------------------------------------------------------------
258 // SparsityPattern inline member functions
259 template<typename BidirectionalIterator>
260 inline
261 void SparsityPattern::sort_row (const BidirectionalIterator begin,
262  BidirectionalIterator middle,
263  const BidirectionalIterator end)
264 {
265  // Assure we have the conditions for an inplace_merge
266 #ifdef DEBUG
267  libmesh_assert(std::is_sorted(begin, middle));
268  libmesh_assert(std::is_sorted(middle, end));
269 #endif
270  libmesh_assert(std::unique(begin, middle) == middle);
271  libmesh_assert(std::unique(middle, end) == end);
272 
273  std::inplace_merge(begin, middle, end);
274 
275  // Assure the algorithm worked if we are in DEBUG mode
276 #ifdef DEBUG
277  libmesh_assert (std::is_sorted(begin,end));
278 #endif
279 
280  // Make sure the two ranges did not contain any common elements
281  libmesh_assert (std::unique (begin, end) == end);
282 }
283 
284 } // namespace libMesh
285 
286 #endif // LIBMESH_SPARSITY_PATTERN_H
SparsityPattern::Graph sparsity_pattern
A class holding degree of freedom information pertinent to static condensation.
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
const std::set< GhostingFunctor * > & coupling_functors
void apply_extra_sparsity_function(void(*func)(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *context), void *context)
Let a user-provided function modify our sparsity structure.
const std::vector< dof_id_type > & get_n_oz() const
The number of off-processor nonzeros in my portion of the global matrix.
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
Definition: threads_none.h:63
std::size_t n_nonzeros() const
The total number of nonzeros in the global matrix.
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
The libMesh namespace provides an interface to certain functionality in the library.
void parallel_sync()
Send sparsity pattern data relevant to other processors to those processors, and receive and incorpor...
std::unordered_set< dof_id_type > hashed_dof_sets
If there are "spider" nodes in the mesh (i.e.
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
std::vector< dof_id_type > dummy_vec
A dummy work vector to avoid repeated memory allocations.
std::vector< dof_id_type, Threads::scalable_allocator< dof_id_type > > Row
void join(const Build &other)
Combine the sparsity pattern in other with this object&#39;s sparsity pattern.
const SparsityPattern::NonlocalGraph & get_nonlocal_pattern() const
Rows of sparse matrix indices, mapped from global DoF number, which belong on other processors...
const CouplingMatrix * dof_coupling
bool is_sorted(const std::vector< KeyType > &v)
void sorted_connected_dofs(const Elem *elem, std::vector< dof_id_type > &dofs_vi, unsigned int vi)
libmesh_assert(ctx)
std::vector< dof_id_type > n_nz
An object whose state is distributed along a set of processors.
const SparsityPattern::Graph & get_sparsity_pattern() const
Rows of sparse matrix indices, indexed by the offset from the first DoF on this processor.
void apply_extra_sparsity_object(SparsityPattern::AugmentSparsityPattern &asp)
Let a user-provided AugmentSparsityPattern subclass modify our sparsity structure.
const std::vector< dof_id_type > & get_n_nz() const
The number of on-processor nonzeros in my portion of the global matrix.
SparsityPattern::NonlocalGraph nonlocal_pattern
const StaticCondensationDofMap *const sc
void clear_full_sparsity()
Clear the "full" details of our sparsity structure, leaving only the counts of non-zero entries...
void handle_vi_vj(const std::vector< dof_id_type > &element_dofs_i, const std::vector< dof_id_type > &element_dofs_j)
void operator()(const ConstElemRange &range)
Add entries from a range of elements to this object&#39;s sparsity pattern.
virtual void augment_sparsity_pattern(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz)=0
User-defined function to augment the sparsity pattern.
Build(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, const bool calculate_constrained_in=false, const StaticCondensationDofMap *sc=nullptr)
Abstract base class to be used to add user-defined implicit degree of freedom couplings.
Build & operator=(const Build &)=delete
This class defines a coupling matrix.
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...
std::vector< dof_id_type > n_oz