Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/dolfinx/v0.9.0/cpp/doxygen/d8/de3/AdjacencyList_8h_source.html
DOLFINx 0.6.0
DOLFINx C++ interface
Loading...
Searching...
No Matches
AdjacencyList.h
1// Copyright (C) 2019-2022 Garth N. Wells
2//
3// This file is part of DOLFINx (https://www.fenicsproject.org)
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6
7#pragma once
8
9#include <cassert>
10#include <concepts>
11#include <numeric>
12#include <span>
13#include <sstream>
14#include <utility>
15#include <vector>
16
17namespace dolfinx::graph
18{
19
25template <typename T>
27{
28public:
32 explicit AdjacencyList(const std::int32_t n) : _array(n), _offsets(n + 1)
33 {
34 std::iota(_array.begin(), _array.end(), 0);
35 std::iota(_offsets.begin(), _offsets.end(), 0);
36 }
37
42 template <std::convertible_to<std::vector<T>> U,
43 std::convertible_to<std::vector<std::int32_t>> V>
44 AdjacencyList(U&& data, V&& offsets)
45 : _array(std::forward<U>(data)), _offsets(std::forward<V>(offsets))
46 {
47 _array.reserve(_offsets.back());
48 assert(_offsets.back() == (std::int32_t)_array.size());
49 }
50
56 template <typename X>
57 explicit AdjacencyList(const std::vector<X>& data)
58 {
59 // Initialize offsets and compute total size
60 _offsets.reserve(data.size() + 1);
61 _offsets.push_back(0);
62 for (const auto& row : data)
63 _offsets.push_back(_offsets.back() + row.size());
64
65 _array.reserve(_offsets.back());
66 for (const auto& e : data)
67 _array.insert(_array.end(), e.begin(), e.end());
68 }
69
71 AdjacencyList(const AdjacencyList& list) = default;
72
74 AdjacencyList(AdjacencyList&& list) = default;
75
77 ~AdjacencyList() = default;
78
80 AdjacencyList& operator=(const AdjacencyList& list) = default;
81
84
87 bool operator==(const AdjacencyList& list) const
88 {
89 return this->_array == list._array and this->_offsets == list._offsets;
90 }
91
94 std::int32_t num_nodes() const { return _offsets.size() - 1; }
95
99 int num_links(int node) const
100 {
101 assert((node + 1) < (int)_offsets.size());
102 return _offsets[node + 1] - _offsets[node];
103 }
104
109 std::span<T> links(int node)
110 {
111 return std::span<T>(_array.data() + _offsets[node],
112 _offsets[node + 1] - _offsets[node]);
113 }
114
119 std::span<const T> links(int node) const
120 {
121 return std::span<const T>(_array.data() + _offsets[node],
122 _offsets[node + 1] - _offsets[node]);
123 }
124
126 const std::vector<T>& array() const { return _array; }
127
129 std::vector<T>& array() { return _array; }
130
132 const std::vector<std::int32_t>& offsets() const { return _offsets; }
133
135 std::vector<std::int32_t>& offsets() { return _offsets; }
136
139 std::string str() const
140 {
141 std::stringstream s;
142 s << "<AdjacencyList> with " + std::to_string(this->num_nodes()) + " nodes"
143 << std::endl;
144 for (std::size_t e = 0; e < _offsets.size() - 1; ++e)
145 {
146 s << " " << e << ": [";
147 for (auto link : this->links(e))
148 s << link << " ";
149 s << "]" << std::endl;
150 }
151 return s.str();
152 }
153
154private:
155 // Connections for all entities stored as a contiguous array
156 std::vector<T> _array;
157
158 // Position of first connection for each entity (using local index)
159 std::vector<std::int32_t> _offsets;
160};
161
169template <typename U>
170 requires requires {
171 typename std::decay_t<U>::value_type;
172 std::convertible_to<
173 U, std::vector<typename std::decay_t<U>::value_type>>;
174 }
175AdjacencyList<typename std::decay_t<U>::value_type>
176regular_adjacency_list(U&& data, int degree)
177{
178 if (degree == 0 and !data.empty())
179 {
180 throw std::runtime_error("Degree is zero but data is not empty for "
181 "constant degree AdjacencyList");
182 }
183
184 if (degree > 0 and data.size() % degree != 0)
185 {
186 throw std::runtime_error(
187 "Incompatible data size and degree for constant degree AdjacencyList");
188 }
189
190 std::int32_t num_nodes = degree == 0 ? data.size() : data.size() / degree;
191 std::vector<std::int32_t> offsets(num_nodes + 1, 0);
192 for (std::size_t i = 1; i < offsets.size(); ++i)
193 offsets[i] = offsets[i - 1] + degree;
195 std::forward<U>(data), std::move(offsets));
196}
197
198} // namespace dolfinx::graph
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:27
std::span< T > links(int node)
Get the links (edges) for given node.
Definition: AdjacencyList.h:109
bool operator==(const AdjacencyList &list) const
Equality operator.
Definition: AdjacencyList.h:87
std::vector< std::int32_t > & offsets()
Offset for each node in array()
Definition: AdjacencyList.h:135
const std::vector< T > & array() const
Return contiguous array of links for all nodes (const version)
Definition: AdjacencyList.h:126
AdjacencyList & operator=(AdjacencyList &&list)=default
Move assignment operator.
int num_links(int node) const
Number of connections for given node.
Definition: AdjacencyList.h:99
AdjacencyList(const std::int32_t n)
Construct trivial adjacency list where each of the n nodes is connected to itself.
Definition: AdjacencyList.h:32
AdjacencyList(AdjacencyList &&list)=default
Move constructor.
AdjacencyList & operator=(const AdjacencyList &list)=default
Assignment operator.
AdjacencyList(const std::vector< X > &data)
Set all connections for all entities (T is a '2D' container, e.g. a std::vector<<std::vector<std::siz...
Definition: AdjacencyList.h:57
std::int32_t num_nodes() const
Get the number of nodes.
Definition: AdjacencyList.h:94
AdjacencyList(const AdjacencyList &list)=default
Copy constructor.
std::vector< T > & array()
Return contiguous array of links for all nodes.
Definition: AdjacencyList.h:129
std::span< const T > links(int node) const
Get the links (edges) for given node (const version)
Definition: AdjacencyList.h:119
const std::vector< std::int32_t > & offsets() const
Offset for each node in array() (const version)
Definition: AdjacencyList.h:132
std::string str() const
Informal string representation (pretty-print)
Definition: AdjacencyList.h:139
~AdjacencyList()=default
Destructor.
AdjacencyList(U &&data, V &&offsets)
Construct adjacency list from arrays of data.
Definition: AdjacencyList.h:44
Graph data structures and algorithms.
Definition: dofmapbuilder.h:25
AdjacencyList< typename std::decay_t< U >::value_type > regular_adjacency_list(U &&data, int degree)
Construct a constant degree (valency) adjacency list.
Definition: AdjacencyList.h:176