Reference documentation for deal.II version GIT c00406db16 2023-09-28 18:00:02+00:00
\(\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\}}\)
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 
23 #include <deal.II/base/logstream.h>
25 
26 #include <algorithm>
27 #include <cstddef>
28 #include <string>
29 #include <vector>
30 
32 
33 
60 class BlockIndices : public Subscriptor
61 {
62 public:
67 
71  BlockIndices();
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 
134  size_type
135  total_size() const;
136 
140  size_type
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 
174  size_type
175  local_to_global(const unsigned int block, const size_type index) const;
176 
180  size_type
181  block_start(const unsigned int i) const;
187  BlockIndices &
188  operator=(const BlockIndices &b);
189 
194  BlockIndices &
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 
217 private:
222  unsigned int n_blocks;
223 
228  std::vector<size_type> start_indices;
229 };
230 
231 
238 inline LogStream &
239 operator<<(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 
257 inline void
258 BlockIndices::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 
268 inline void
269 BlockIndices::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 
289 inline 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 
300 inline 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 
319 inline void
321 {
322  start_indices.push_back(start_indices[n_blocks] + sz);
323  ++n_blocks;
325 }
326 
327 
328 inline 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 
343 BlockIndices::local_to_global(const unsigned int block,
344  const size_type index) const
345 {
346  AssertIndexRange(block, n_blocks);
347  AssertIndexRange(index, start_indices[block + 1] - start_indices[block]);
348 
349  return start_indices[block] + index;
350 }
351 
352 
353 inline 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 
372 BlockIndices::block_size(const unsigned int block) const
373 {
374  AssertIndexRange(block, n_blocks);
375  return start_indices[block + 1] - start_indices[block];
376 }
377 
378 
379 
380 inline 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 
397 BlockIndices::block_start(const unsigned int block) const
398 {
399  AssertIndexRange(block, n_blocks);
400  return start_indices[block];
401 }
402 
403 
404 
405 inline BlockIndices &
407 {
408  start_indices = b.start_indices;
409  n_blocks = b.n_blocks;
410  return *this;
411 }
412 
413 
414 
415 inline 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 
429 inline 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 
444 inline void
446 {
447  std::swap(n_blocks, b.n_blocks);
448  std::swap(start_indices, b.start_indices);
449 }
450 
451 
452 
453 inline std::size_t
455 {
456  return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
457 }
458 
459 
460 
461 /* ----------------- global functions ---------------------------- */
462 
463 
471 inline void
473 {
474  u.swap(v);
475 }
476 
477 
478 
480 
481 #endif
void swap(BlockIndices &u, BlockIndices &v)
std::string to_string() const
types::global_dof_index size_type
Definition: block_indices.h:66
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:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
#define Assert(cond, exc)
Definition: exceptions.h:1616
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1789
#define AssertIndexRange(index, range)
Definition: exceptions.h:1857
constexpr int block_size
Definition: cuda_size.h:29
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
Definition: operators.h:50
std::string to_string(const T &t)
Definition: patterns.h:2391
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
unsigned int global_dof_index
Definition: types.h:82