Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
block_indices.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2019 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 
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/logstream.h>
24 #include <deal.II/base/subscriptor.h>
25 #include <deal.II/base/utilities.h>
26 
27 #include <cstddef>
28 #include <vector>
29 
30 DEAL_II_NAMESPACE_OPEN
31 
32 
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 
123 
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 
152 
162 
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;
183 
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 
229 };
230 
231 
240 inline LogStream &
241 operator<<(LogStream &s, const BlockIndices &bi)
242 {
243  const unsigned int n = bi.size();
244  s << n << ":[";
245  // Write first size without leading space
246  if (n > 0)
247  s << bi.block_size(0);
248  // Write all other sizes
249  for (unsigned int i = 1; i < n; ++i)
250  s << ' ' << bi.block_size(i);
251  s << "]->" << bi.total_size();
252  return s;
253 }
254 
255 
256 
257 /* ---------------------- template and inline functions ------------------- */
258 
259 inline void
260 BlockIndices::reinit(const unsigned int nb, const size_type block_size)
261 {
262  n_blocks = nb;
263  start_indices.resize(n_blocks + 1);
264  for (size_type i = 0; i <= n_blocks; ++i)
265  start_indices[i] = i * block_size;
266 }
267 
268 
269 
270 inline void
271 BlockIndices::reinit(const std::vector<size_type> &block_sizes)
272 {
273  if (start_indices.size() != block_sizes.size() + 1)
274  {
275  n_blocks = static_cast<unsigned int>(block_sizes.size());
276  start_indices.resize(n_blocks + 1);
277  }
278  start_indices[0] = 0;
279  for (size_type i = 1; i <= n_blocks; ++i)
280  start_indices[i] = start_indices[i - 1] + block_sizes[i - 1];
281 }
282 
283 
285  : n_blocks(0)
286  , start_indices(1, 0)
287 {}
288 
289 
290 
291 inline BlockIndices::BlockIndices(const unsigned int n_blocks,
292  const size_type block_size)
293  : n_blocks(n_blocks)
294  , start_indices(n_blocks + 1)
295 {
296  for (size_type i = 0; i <= n_blocks; ++i)
297  start_indices[i] = i * block_size;
298 }
299 
300 
301 
302 inline BlockIndices::BlockIndices(const std::vector<size_type> &block_sizes)
303  : n_blocks(static_cast<unsigned int>(block_sizes.size()))
304  , start_indices(block_sizes.size() + 1)
305 {
306  reinit(block_sizes);
307 }
308 
309 
310 
312  : n_blocks(b.n_blocks)
313  , start_indices(std::move(b.start_indices))
314 {
315  b.n_blocks = 0;
316  b.start_indices = std::vector<size_type>(1, 0);
317 }
318 
319 
320 
321 inline void
323 {
324  start_indices.push_back(start_indices[n_blocks] + sz);
325  ++n_blocks;
327 }
328 
329 
330 inline std::pair<unsigned int, BlockIndices::size_type>
332 {
333  Assert(i < total_size(), ExcIndexRangeType<size_type>(i, 0, total_size()));
334  Assert(n_blocks > 0, ExcLowerRangeType<size_type>(i, size_type(1)));
335 
336  // start_indices[0] == 0 so we might as well start from the next one
337  const auto it =
338  --std::upper_bound(++start_indices.begin(), start_indices.end(), i);
339 
340  return {std::distance(start_indices.begin(), it), i - *it};
341 }
342 
343 
345 BlockIndices::local_to_global(const unsigned int block,
346  const size_type index) const
347 {
348  Assert(block < n_blocks, ExcIndexRange(block, 0, n_blocks));
349  Assert(index < start_indices[block + 1] - start_indices[block],
350  ExcIndexRangeType<size_type>(
351  index, 0, start_indices[block + 1] - start_indices[block]));
352 
353  return start_indices[block] + index;
354 }
355 
356 
357 inline unsigned int
359 {
360  return n_blocks;
361 }
362 
363 
364 
367 {
368  if (n_blocks == 0)
369  return 0;
370  return start_indices[n_blocks];
371 }
372 
373 
374 
376 BlockIndices::block_size(const unsigned int block) const
377 {
378  Assert(block < n_blocks, ExcIndexRange(block, 0, n_blocks));
379  return start_indices[block + 1] - start_indices[block];
380 }
381 
382 
383 
384 inline std::string
386 {
387  std::string result = "[" + Utilities::int_to_string(n_blocks) + "->";
388  for (unsigned int i = 0; i < n_blocks; ++i)
389  {
390  if (i > 0)
391  result += ',';
392  result += Utilities::to_string(block_size(i));
393  }
394  result += "|" + Utilities::to_string(total_size()) + ']';
395  return result;
396 }
397 
398 
399 
401 BlockIndices::block_start(const unsigned int block) const
402 {
403  Assert(block < n_blocks, ExcIndexRange(block, 0, n_blocks));
404  return start_indices[block];
405 }
406 
407 
408 
409 inline BlockIndices &
411 {
412  start_indices = b.start_indices;
413  n_blocks = b.n_blocks;
414  return *this;
415 }
416 
417 
418 
419 inline BlockIndices &
421 {
422  start_indices = std::move(b.start_indices);
423  n_blocks = b.n_blocks;
424 
425  b.start_indices = std::vector<size_type>(1, 0);
426  b.n_blocks = 0;
427 
428  return *this;
429 }
430 
431 
432 
433 inline bool
435 {
436  if (n_blocks != b.n_blocks)
437  return false;
438 
439  for (size_type i = 0; i <= n_blocks; ++i)
440  if (start_indices[i] != b.start_indices[i])
441  return false;
442 
443  return true;
444 }
445 
446 
447 
448 inline void
450 {
451  std::swap(n_blocks, b.n_blocks);
452  std::swap(start_indices, b.start_indices);
453 }
454 
455 
456 
457 inline std::size_t
459 {
460  return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
461 }
462 
463 
464 
465 /* ----------------- global functions ---------------------------- */
466 
467 
476 inline void
478 {
479  u.swap(v);
480 }
481 
482 
483 
484 DEAL_II_NAMESPACE_CLOSE
485 
486 #endif
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1567
STL namespace.
size_type block_size(const unsigned int i) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:392
size_type total_size() const
unsigned int n_blocks
void swap(BlockIndices &u, BlockIndices &v)
bool operator==(const BlockIndices &b) const
#define Assert(cond, exc)
Definition: exceptions.h:1407
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
std::string to_string() const
size_type local_to_global(const unsigned int block, const size_type index) const
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:383
std::vector< size_type > start_indices
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1376
unsigned int global_dof_index
Definition: types.h:89
BlockIndices & operator=(const BlockIndices &b)
std::size_t memory_consumption() const
size_type block_start(const unsigned int i) const
void push_back(const size_type size)
void swap(BlockIndices &b)
types::global_dof_index size_type
Definition: block_indices.h:66
unsigned int size() const
std::pair< unsigned int, size_type > global_to_local(const size_type i) const