Reference documentation for deal.II version Git 54f37b890c 2020-02-28 19:52:28 +0100
\(\newcommand{\vcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\vcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
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 {
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  AssertIndexRange(block, n_blocks);
349  AssertIndexRange(index, start_indices[block + 1] - start_indices[block]);
350 
351  return start_indices[block] + index;
352 }
353 
354 
355 inline unsigned int
357 {
358  return n_blocks;
359 }
360 
361 
362 
365 {
366  if (n_blocks == 0)
367  return 0;
368  return start_indices[n_blocks];
369 }
370 
371 
372 
374 BlockIndices::block_size(const unsigned int block) const
375 {
376  AssertIndexRange(block, n_blocks);
377  return start_indices[block + 1] - start_indices[block];
378 }
379 
380 
381 
382 inline std::string
384 {
385  std::string result = "[" + Utilities::int_to_string(n_blocks) + "->";
386  for (unsigned int i = 0; i < n_blocks; ++i)
387  {
388  if (i > 0)
389  result += ',';
390  result += std::to_string(block_size(i));
391  }
392  result += "|" + std::to_string(total_size()) + ']';
393  return result;
394 }
395 
396 
397 
399 BlockIndices::block_start(const unsigned int block) const
400 {
401  AssertIndexRange(block, n_blocks);
402  return start_indices[block];
403 }
404 
405 
406 
407 inline BlockIndices &
409 {
411  n_blocks = b.n_blocks;
412  return *this;
413 }
414 
415 
416 
417 inline BlockIndices &
419 {
420  start_indices = std::move(b.start_indices);
421  n_blocks = b.n_blocks;
422 
423  b.start_indices = std::vector<size_type>(1, 0);
424  b.n_blocks = 0;
425 
426  return *this;
427 }
428 
429 
430 
431 inline bool
433 {
434  if (n_blocks != b.n_blocks)
435  return false;
436 
437  for (size_type i = 0; i <= n_blocks; ++i)
438  if (start_indices[i] != b.start_indices[i])
439  return false;
440 
441  return true;
442 }
443 
444 
445 
446 inline void
448 {
451 }
452 
453 
454 
455 inline std::size_t
457 {
458  return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
459 }
460 
461 
462 
463 /* ----------------- global functions ---------------------------- */
464 
465 
474 inline void
476 {
477  u.swap(v);
478 }
479 
480 
481 
482 DEAL_II_NAMESPACE_CLOSE
483 
484 #endif
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1571
#define AssertIndexRange(index, range)
Definition: exceptions.h:1641
STL namespace.
size_type block_size(const unsigned int i) const
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:1411
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:429
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