Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/v0.1.0/v0.9.0/cpp
DOLFINx  0.1.0
DOLFINx C++ interface
AdjacencyList.h
1 // Copyright (C) 2006-2019 Anders Logg and 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 <dolfinx/common/array2d.h>
11 #include <numeric>
12 #include <sstream>
13 #include <utility>
14 #include <vector>
15 #include <xtensor/xtensor.hpp>
16 #include <xtl/xspan.hpp>
17 
18 namespace dolfinx::graph
19 {
20 
26 template <typename T>
27 auto create_adjacency_data(const xt::xtensor<T, 2>& array)
28 {
29  std::vector<T> data(array.shape(0) * array.shape(1));
30  std::vector<std::int32_t> offset(array.shape(0) + 1, 0);
31  for (std::size_t i = 0; i < array.shape(0); ++i)
32  {
33  for (std::size_t j = 0; j < array.shape(1); ++j)
34  data[i * array.shape(1) + j] = array(i, j);
35  offset[i + 1] = offset[i] + array.shape(1);
36  }
37  return std::pair(std::move(data), std::move(offset));
38 }
39 
45 template <typename T>
47 {
48 public:
52  explicit AdjacencyList(const std::int32_t n) : _array(n), _offsets(n + 1)
53  {
54  std::iota(_array.begin(), _array.end(), 0);
55  std::iota(_offsets.begin(), _offsets.end(), 0);
56  }
57 
62  template <
63  typename U, typename V,
64  typename = std::enable_if_t<
65  std::is_same<std::vector<T>, std::decay_t<U>>::value
66  && std::is_same<std::vector<std::int32_t>, std::decay_t<V>>::value>>
67  AdjacencyList(U&& data, V&& offsets)
68  : _array(std::forward<U>(data)), _offsets(std::forward<V>(offsets))
69  {
70  _array.reserve(_offsets.back());
71  assert(_offsets.back() == (std::int32_t)_array.size());
72  }
73 
78  template <typename X>
79  explicit AdjacencyList(const std::vector<X>& data)
80  {
81  // Initialize offsets and compute total size
82  _offsets.reserve(data.size() + 1);
83  _offsets.push_back(0);
84  for (auto row = data.begin(); row != data.end(); ++row)
85  _offsets.push_back(_offsets.back() + row->size());
86 
87  _array.reserve(_offsets.back());
88  for (auto e = data.begin(); e != data.end(); ++e)
89  _array.insert(_array.end(), e->begin(), e->end());
90  }
91 
93  AdjacencyList(const AdjacencyList& list) = default;
94 
96  AdjacencyList(AdjacencyList&& list) = default;
97 
99  ~AdjacencyList() = default;
100 
102  AdjacencyList& operator=(const AdjacencyList& list) = default;
103 
105  AdjacencyList& operator=(AdjacencyList&& list) = default;
106 
108  bool operator==(const AdjacencyList& list) const
109  {
110  return this->_array == list._array and this->_offsets == list._offsets;
111  }
112 
115  std::int32_t num_nodes() const { return _offsets.size() - 1; }
116 
120  int num_links(int node) const
121  {
122  assert((node + 1) < (int)_offsets.size());
123  return _offsets[node + 1] - _offsets[node];
124  }
125 
130  xtl::span<T> links(int node)
131  {
132  return xtl::span<T>(_array.data() + _offsets[node],
133  _offsets[node + 1] - _offsets[node]);
134  }
135 
140  xtl::span<const T> links(int node) const
141  {
142  return xtl::span<const T>(_array.data() + _offsets[node],
143  _offsets[node + 1] - _offsets[node]);
144  }
145 
147  const std::vector<T>& array() const { return _array; }
148 
150  std::vector<T>& array() { return _array; }
151 
153  const std::vector<std::int32_t>& offsets() const { return _offsets; }
154 
157  template <typename X>
158  decltype(auto) as_type() const
159  {
160 // Workaround for Intel compler bug, see
161 // https://community.intel.com/t5/Intel-C-Compiler/quot-if-constexpr-quot-and-quot-missing-return-statement-quot-in/td-p/1154551
162 #ifdef __INTEL_COMPILER
163 #pragma warning(disable : 1011)
164 #endif
165 
166  if constexpr (std::is_same<X, T>::value)
167  return *this;
168  else
169  {
171  std::vector<X>(_array.begin(), _array.end()), this->_offsets);
172  }
173  }
174 
176  std::string str() const
177  {
178  std::stringstream s;
179  s << "<AdjacencyList> with " + std::to_string(this->num_nodes()) + " nodes"
180  << std::endl;
181  for (std::size_t e = 0; e < _offsets.size() - 1; ++e)
182  {
183  s << " " << e << ": [";
184  for (auto link : this->links(e))
185  s << link << " ";
186  s << "]" << std::endl;
187  }
188  return s.str();
189  }
190 
191 private:
192  // Connections for all entities stored as a contiguous array
193  std::vector<T> _array;
194 
195  // Position of first connection for each entity (using local index)
196  std::vector<std::int32_t> _offsets;
197 };
198 
205 template <typename T, typename U>
207 {
208  // using T = typename U::value_type;
209  assert(data.size() % degree == 0);
210  std::vector<std::int32_t> offsets(data.size() / degree + 1, 0);
211  for (std::size_t i = 1; i < offsets.size(); ++i)
212  offsets[i] = offsets[i - 1] + degree;
213  return AdjacencyList<T>(std::forward<U>(data), std::move(offsets));
214 }
215 
216 } // namespace dolfinx::graph
dolfinx::graph::AdjacencyList::as_type
decltype(auto) as_type() const
Copy of the Adjacency List if the specified type is different from the current type,...
Definition: AdjacencyList.h:158
dolfinx::graph::AdjacencyList::num_links
int num_links(int node) const
Number of connections for given node.
Definition: AdjacencyList.h:120
dolfinx::graph::AdjacencyList::num_nodes
std::int32_t num_nodes() const
Get the number of nodes.
Definition: AdjacencyList.h:115
dolfinx::graph::AdjacencyList::links
xtl::span< const T > links(int node) const
Get the links (edges) for given node (const version)
Definition: AdjacencyList.h:140
dolfinx::graph
Graph data structures and algorithms.
Definition: AdjacencyList.h:18
dolfinx::graph::AdjacencyList::array
std::vector< T > & array()
Return contiguous array of links for all nodes.
Definition: AdjacencyList.h:150
dolfinx::graph::AdjacencyList::AdjacencyList
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:79
dolfinx::graph::create_adjacency_data
auto create_adjacency_data(const xt::xtensor< T, 2 > &array)
Construct adjacency list data for a problem with a fixed number of links (edges) for each node.
Definition: AdjacencyList.h:27
dolfinx::graph::build_adjacency_list
AdjacencyList< T > build_adjacency_list(U &&data, int degree)
Construct an adjacency list from array of data for a graph with constant degree (valency)....
Definition: AdjacencyList.h:206
dolfinx::graph::AdjacencyList
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:46
dolfinx::graph::AdjacencyList::array
const std::vector< T > & array() const
Return contiguous array of links for all nodes (const version)
Definition: AdjacencyList.h:147
dolfinx::graph::AdjacencyList::AdjacencyList
AdjacencyList(const std::int32_t n)
Construct trivial adjacency list where each of the n nodes is connected to itself.
Definition: AdjacencyList.h:52
dolfinx::graph::AdjacencyList::str
std::string str() const
Return informal string representation (pretty-print)
Definition: AdjacencyList.h:176
dolfinx::graph::AdjacencyList::operator=
AdjacencyList & operator=(const AdjacencyList &list)=default
Assignment.
dolfinx::graph::AdjacencyList::AdjacencyList
AdjacencyList(U &&data, V &&offsets)
Construct adjacency list from arrays of data.
Definition: AdjacencyList.h:67
dolfinx::graph::AdjacencyList::~AdjacencyList
~AdjacencyList()=default
Destructor.
dolfinx::graph::AdjacencyList::operator==
bool operator==(const AdjacencyList &list) const
Equality operator.
Definition: AdjacencyList.h:108
dolfinx::graph::AdjacencyList::links
xtl::span< T > links(int node)
Get the links (edges) for given node.
Definition: AdjacencyList.h:130
dolfinx::graph::AdjacencyList::offsets
const std::vector< std::int32_t > & offsets() const
Offset for each node in array() (const version)
Definition: AdjacencyList.h:153