Reference documentation for deal.II version 9.5.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
block_indices.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2000 - 2022 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_block_indices_h
17#define dealii_block_indices_h
18
19
20#include <deal.II/base/config.h>
21
25
26#include <algorithm>
27#include <cstddef>
28#include <string>
29#include <vector>
30
32
33
61{
62public:
67
72
78 BlockIndices(const std::vector<size_type> &block_sizes);
79
84 BlockIndices(BlockIndices &&b) noexcept;
85
89 BlockIndices(const BlockIndices &) = default;
90
94 explicit BlockIndices(const unsigned int n_blocks,
95 const size_type block_size = 0);
96
101 void
102 reinit(const unsigned int n_blocks, const size_type n_elements_per_block);
103
110 void
111 reinit(const std::vector<size_type> &block_sizes);
112
116 void
117 push_back(const size_type size);
118
127 unsigned int
128 size() const;
129
135 total_size() const;
136
141 block_size(const unsigned int i) const;
142
148 std::string
149 to_string() const;
150
168 std::pair<unsigned int, size_type>
169 global_to_local(const size_type i) const;
170
175 local_to_global(const unsigned int block, const size_type index) const;
176
181 block_start(const unsigned int i) const;
188 operator=(const BlockIndices &b);
189
195 operator=(BlockIndices &&) noexcept;
196
201 bool
202 operator==(const BlockIndices &b) const;
203
207 void
208 swap(BlockIndices &b);
209
214 std::size_t
215 memory_consumption() const;
216
217private:
222 unsigned int n_blocks;
223
229};
230
231
238inline LogStream &
239operator<<(LogStream &s, const BlockIndices &bi)
240{
241 const unsigned int n = bi.size();
242 s << n << ":[";
243 // Write first size without leading space
244 if (n > 0)
245 s << bi.block_size(0);
246 // Write all other sizes
247 for (unsigned int i = 1; i < n; ++i)
248 s << ' ' << bi.block_size(i);
249 s << "]->" << bi.total_size();
250 return s;
251}
252
253
254
255/* ---------------------- template and inline functions ------------------- */
256
257inline void
258BlockIndices::reinit(const unsigned int nb, const size_type block_size)
259{
260 n_blocks = nb;
261 start_indices.resize(n_blocks + 1);
262 for (size_type i = 0; i <= n_blocks; ++i)
263 start_indices[i] = i * block_size;
264}
265
266
267
268inline void
269BlockIndices::reinit(const std::vector<size_type> &block_sizes)
270{
271 if (start_indices.size() != block_sizes.size() + 1)
272 {
273 n_blocks = static_cast<unsigned int>(block_sizes.size());
274 start_indices.resize(n_blocks + 1);
275 }
276 start_indices[0] = 0;
277 for (size_type i = 1; i <= n_blocks; ++i)
278 start_indices[i] = start_indices[i - 1] + block_sizes[i - 1];
279}
280
281
283 : n_blocks(0)
284 , start_indices(1, 0)
285{}
286
287
288
289inline BlockIndices::BlockIndices(const unsigned int n_blocks,
290 const size_type block_size)
291 : n_blocks(n_blocks)
292 , start_indices(n_blocks + 1)
293{
294 for (size_type i = 0; i <= n_blocks; ++i)
295 start_indices[i] = i * block_size;
296}
297
298
299
300inline BlockIndices::BlockIndices(const std::vector<size_type> &block_sizes)
301 : n_blocks(static_cast<unsigned int>(block_sizes.size()))
302 , start_indices(block_sizes.size() + 1)
303{
304 reinit(block_sizes);
305}
306
307
308
310 : n_blocks(b.n_blocks)
311 , start_indices(std::move(b.start_indices))
312{
313 b.n_blocks = 0;
314 b.start_indices = std::vector<size_type>(1, 0);
315}
316
317
318
319inline void
321{
322 start_indices.push_back(start_indices[n_blocks] + sz);
323 ++n_blocks;
325}
326
327
328inline std::pair<unsigned int, BlockIndices::size_type>
330{
332 Assert(n_blocks > 0, ExcLowerRangeType<size_type>(i, size_type(1)));
333
334 // start_indices[0] == 0 so we might as well start from the next one
335 const auto it = std::prev(
336 std::upper_bound(std::next(start_indices.begin()), start_indices.end(), i));
337
338 return {std::distance(start_indices.begin(), it), i - *it};
339}
340
341
343BlockIndices::local_to_global(const unsigned int block,
344 const size_type index) const
345{
347 AssertIndexRange(index, start_indices[block + 1] - start_indices[block]);
348
349 return start_indices[block] + index;
350}
351
352
353inline unsigned int
355{
356 return n_blocks;
357}
358
359
360
363{
364 if (n_blocks == 0)
365 return 0;
366 return start_indices[n_blocks];
367}
368
369
370
372BlockIndices::block_size(const unsigned int block) const
373{
375 return start_indices[block + 1] - start_indices[block];
376}
377
378
379
380inline std::string
382{
383 std::string result = "[" + std::to_string(n_blocks) + "->";
384 for (unsigned int i = 0; i < n_blocks; ++i)
385 {
386 if (i > 0)
387 result += ',';
388 result += std::to_string(block_size(i));
389 }
390 result += "|" + std::to_string(total_size()) + ']';
391 return result;
392}
393
394
395
397BlockIndices::block_start(const unsigned int block) const
398{
400 return start_indices[block];
401}
402
403
404
405inline BlockIndices &
407{
408 start_indices = b.start_indices;
409 n_blocks = b.n_blocks;
410 return *this;
411}
412
413
414
415inline BlockIndices &
417{
418 start_indices = std::move(b.start_indices);
419 n_blocks = b.n_blocks;
420
421 b.start_indices = std::vector<size_type>(1, 0);
422 b.n_blocks = 0;
423
424 return *this;
425}
426
427
428
429inline bool
431{
432 if (n_blocks != b.n_blocks)
433 return false;
434
435 for (size_type i = 0; i <= n_blocks; ++i)
436 if (start_indices[i] != b.start_indices[i])
437 return false;
438
439 return true;
440}
441
442
443
444inline void
446{
447 std::swap(n_blocks, b.n_blocks);
448 std::swap(start_indices, b.start_indices);
449}
450
451
452
453inline std::size_t
455{
456 return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
457}
458
459
460
461/* ----------------- global functions ---------------------------- */
462
463
471inline void
473{
474 u.swap(v);
475}
476
477
478
480
481#endif
std::string to_string() const
types::global_dof_index size_type
BlockIndices(const BlockIndices &)=default
size_type block_size(const unsigned int i) const
unsigned int n_blocks
void push_back(const size_type size)
BlockIndices & operator=(const BlockIndices &b)
size_type total_size() const
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
std::vector< size_type > start_indices
bool operator==(const BlockIndices &b) const
unsigned int size() const
size_type local_to_global(const unsigned int block, const size_type index) const
void swap(BlockIndices &u, BlockIndices &v)
size_type block_start(const unsigned int i) const
void swap(BlockIndices &b)
std::size_t memory_consumption() const
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
STL namespace.
unsigned int global_dof_index
Definition types.h:82