FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
graph.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#include <kernel/adjacency/graph.hpp>
7#include <kernel/adjacency/permutation.hpp>
8
9#include <algorithm> // for std::max/min/sort
10
11namespace FEAT
12{
13 namespace Adjacency
14 {
16 _num_nodes_image(0),
17 _domain_ptr(),
18 _image_idx()
19 {
20 }
21
22 // allocation constructor
24 Index num_nodes_domain,
25 Index num_nodes_image,
26 Index num_indices_image) :
27 _num_nodes_image(num_nodes_image),
28 _domain_ptr(num_nodes_domain + 1),
29 _image_idx(num_indices_image)
30 {
31 }
32
33 // "Copy-Array" Constructor
35 Index num_nodes_domain,
36 Index num_nodes_image,
37 Index num_indices_image,
38 const Index* domain_ptr,
39 const Index* image_idx) :
40 _num_nodes_image(num_nodes_image),
41 _domain_ptr(num_nodes_domain + 1),
42 _image_idx(num_indices_image)
43 {
44 FEAT_PRAGMA_OMP(parallel for)
45 for(Index i = 0; i <= num_nodes_domain; ++i)
46 {
47 _domain_ptr[i] = domain_ptr[i];
48 }
49 FEAT_PRAGMA_OMP(parallel for)
50 for(Index i = 0; i < num_indices_image; ++i)
51 {
52 _image_idx[i] = image_idx[i];
53 }
54 }
55
56 // "Copy-Vectors" Constructor
58 Index num_nodes_image,
59 const IndexVector& domain_ptr,
60 const IndexVector& image_idx) :
61 _num_nodes_image(num_nodes_image),
62 _domain_ptr(domain_ptr),
63 _image_idx(image_idx)
64 {
65 }
66
67 // "Move-Vectors" Constructor
69 Index num_nodes_image,
70 IndexVector&& domain_ptr,
71 IndexVector&& image_idx) :
72 _num_nodes_image(num_nodes_image),
73 _domain_ptr(std::forward<IndexVector>(domain_ptr)),
74 _image_idx(std::forward<IndexVector>(image_idx))
75 {
76 }
77
78 // move ctor
80 _num_nodes_image(other._num_nodes_image),
81 _domain_ptr(std::forward<IndexVector>(other._domain_ptr)),
82 _image_idx(std::forward<IndexVector>(other._image_idx))
83 {
84 other._num_nodes_image = Index(0);
85 other._domain_ptr.clear();
86 other._image_idx.clear();
87 }
88
91 {
92 // avoid self-move
93 if(this == &other)
94 return *this;
95
96 _num_nodes_image = other._num_nodes_image;
97 _domain_ptr = std::forward<IndexVector>(other._domain_ptr);
98 _image_idx = std::forward<IndexVector>(other._image_idx);
99
100 other._num_nodes_image = Index(0);
101 other._domain_ptr.clear();
102 other._image_idx.clear();
103
104 return *this;
105 }
106
107 // "Permutation" copy CTOR
108 Graph::Graph(const Graph& other, const Permutation& domain_perm, const Permutation& image_perm) :
109 _num_nodes_image(other.get_num_nodes_image()),
110 _domain_ptr(other.get_num_nodes_domain()+1),
111 _image_idx(other.get_num_indices())
112 {
113 // get domain permutation
114 const Index* domain_perm_pos = domain_perm.get_perm_pos();
115
116 // calculate new domain vector
117 _domain_ptr[0] = other._domain_ptr[0];
118 for(Index i(0); i < other.get_num_nodes_domain(); ++i)
119 {
120 _domain_ptr[i+1] = other._domain_ptr[domain_perm_pos[i]+1]
121 - other._domain_ptr[domain_perm_pos[i]]
122 + _domain_ptr[i];
123 }
124
125 // get image permutation
126 const Index* image_perm_pos = image_perm.get_perm_pos();
127
128 // calculate new image vector
129 Index count = 0;
130 for(Index i(0); i < other.get_num_nodes_domain(); ++i)
131 {
132 Index _offset = other._domain_ptr[domain_perm_pos[i]];
133 Index _row_end = other._domain_ptr[domain_perm_pos[i]+1];
134 for(Index j(_offset); j < _row_end; ++j)
135 {
136 _image_idx[count] = image_perm_pos[other._image_idx[j]];
137 ++count;
138 }
139 }
140 }
141
142 Graph::Graph(const std::vector<char>& buffer) :
143 _num_nodes_image(0),
144 _domain_ptr(),
145 _image_idx()
146 {
147 // 40 bytes required by header only
148 XASSERTM(buffer.size() >= std::size_t(40u), "invalid buffer size");
149
150 typedef std::uint64_t u64;
151 const u64* v = reinterpret_cast<const u64*>(buffer.data());
152
153 // check magic
154 XASSERTM(v[0] == Graph::magic, "invalid magic number");
155
156 // check buffer size
157 XASSERTM(v[1] == u64(buffer.size()), "invalid buffer size");
158
159 Index domain_ptr_size = Index(v[2]);
160 this->_num_nodes_image = Index(v[3]);
161 Index num_indices_image = Index(v[4]);
162
163 const u64* x = &v[5];
164
165 // allocate and copy domain pointer vector
166 if(domain_ptr_size > Index(0))
167 {
168 this->_domain_ptr = IndexVector(domain_ptr_size+1u);
169 for(Index i(0); i <= this->get_num_nodes_domain(); ++i)
170 this->_domain_ptr[i] = Index(x[i]);
171 x += std::streamoff(this->get_num_nodes_domain() +1u);
172 }
173
174 // allocate and copy image index vector
175 if(num_indices_image > Index(0))
176 {
177 this->_image_idx = IndexVector(num_indices_image);
178 for(Index i(0); i < num_indices_image; ++i)
179 this->_image_idx[i] = Index(x[i]);
180 }
181 }
182
183 // destructor
185 {
186 }
187
189 {
190 _image_idx.clear();
191 _domain_ptr.clear();
193 }
194
196 {
197 Index deg = 0;
198 FEAT_PRAGMA_OMP(parallel for reduction(max:deg))
199 for(Index i = 0; i < _domain_ptr.size()-1; ++i)
200 {
201 deg = std::max(deg, _domain_ptr[i+1] - _domain_ptr[i]);
202 }
203 return deg;
204 }
205
207 {
208 XASSERTM(!_domain_ptr.empty(), "domain pointer vector is missing");
209 XASSERTM(!_image_idx.empty(), "image index vector is missing");
210
211 // loop over all domain nodes
212 FEAT_PRAGMA_OMP(parallel for schedule(dynamic, 1000))
213 for(Index i = 0; i < _domain_ptr.size()-1; ++i)
214 {
215 // let the STL do the sorting work
216 std::sort(_image_idx.begin() + IndexVector::difference_type(_domain_ptr[i]),
217 _image_idx.begin() + IndexVector::difference_type(_domain_ptr[i+1]));
218 }
219 }
220
222 {
223 XASSERTM(!_image_idx.empty(), "image index vector is missing");
224 XASSERT(Index(_image_idx.size()) == inv_perm.size());
225
226 // map all indices
227 FEAT_PRAGMA_OMP(parallel for)
228 for (Index i = 0; i < _image_idx.size(); ++i)
229 {
230 _image_idx[i] = inv_perm.map(_image_idx[i]);
231 }
232 }
233
234 std::vector<char> Graph::serialize() const
235 {
236 // compute buffer size
237 typedef std::uint64_t u64;
238 u64 s = 5u + u64(_domain_ptr.size()) + u64(_image_idx.size());
239 // allocate buffer
240 std::vector<char> buffer(s * 8u);
241 u64* v = reinterpret_cast<u64*>(buffer.data());
242
243 // create header
244 v[0] = Graph::magic;
245 v[1] = s * u64(8); // buffer size
246 v[2] = u64(this->_domain_ptr.size()-1);
247 v[3] = u64(this->_num_nodes_image);
248 v[4] = u64(this->_image_idx.size());
249
250 // empty graph?
251 if(this->_domain_ptr.size() <= Index(1))
252 return buffer;
253
254 XASSERT(!(this->_domain_ptr.empty()));
255
256 // copy domain pointer
257 u64* x = &v[5];
258 for(Index i(0); i < this->_domain_ptr.size(); ++i)
259 x[i] = u64(this->_domain_ptr[i]);
260
261 // copy image indices
262 x += std::streamoff(this->_domain_ptr.size());
263 for(Index i(0); i < this->_image_idx.size(); ++i)
264 x[i] = u64(this->_image_idx[i]);
265
266 // okay
267 return buffer;
268 }
269 } // namespace Adjacency
270} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Adjacency Graph implementation.
Definition: graph.hpp:34
Graph & operator=(Graph &&other)
move-assign operator
Definition: graph.cpp:90
static constexpr std::uint64_t magic
magic number for Graph serialization
Definition: graph.hpp:48
IndexVector _image_idx
Image node index Vector.
Definition: graph.hpp:66
IndexVector _domain_ptr
Domain pointer Vector.
Definition: graph.hpp:59
Graph()
Default constructor.
Definition: graph.cpp:15
std::vector< Index > IndexVector
index vector type
Definition: graph.hpp:37
void sort_indices()
Sorts the image indices to non-descending order.
Definition: graph.cpp:206
Index degree() const
Returns the degree of the graph.
Definition: graph.cpp:195
void permute_indices(const Adjacency::Permutation &inv_perm)
Permutes the image indices.
Definition: graph.cpp:221
void clear()
Clears the graph.
Definition: graph.cpp:188
virtual ~Graph()
virtual destructor
Definition: graph.cpp:184
Index _num_nodes_image
total number of image nodes
Definition: graph.hpp:52
std::vector< char > serialize() const
Serializes the graph into a buffer.
Definition: graph.cpp:234
Index size() const
returns the size of the permutation
Index * get_perm_pos()
returns the permute-position array
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.