deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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\}}\)
Loading...
Searching...
No Matches
block_indices.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2000 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_block_indices_h
14#define dealii_block_indices_h
15
16
17#include <deal.II/base/config.h>
18
22#include <deal.II/base/types.h>
23
24#include <algorithm>
25#include <cstddef>
26#include <string>
27#include <vector>
28
30
31
59{
60public:
65
70
76 BlockIndices(const std::vector<size_type> &block_sizes);
77
82 BlockIndices(BlockIndices &&b) noexcept;
83
87 BlockIndices(const BlockIndices &) = default;
88
92 explicit BlockIndices(const unsigned int n_blocks,
93 const size_type block_size = 0);
94
99 void
100 reinit(const unsigned int n_blocks, const size_type n_elements_per_block);
101
108 void
109 reinit(const std::vector<size_type> &block_sizes);
110
114 void
115 push_back(const size_type size);
116
125 unsigned int
126 size() const;
127
133 total_size() const;
134
139 block_size(const unsigned int i) const;
140
146 std::string
147 to_string() const;
148
166 std::pair<unsigned int, size_type>
167 global_to_local(const size_type i) const;
168
173 local_to_global(const unsigned int block, const size_type index) const;
174
179 block_start(const unsigned int i) const;
186 operator=(const BlockIndices &b);
187
193 operator=(BlockIndices &&) noexcept;
194
199 bool
200 operator==(const BlockIndices &b) const;
201
205 void
206 swap(BlockIndices &b) noexcept;
207
212 std::size_t
213 memory_consumption() const;
214
215private:
220 unsigned int n_blocks;
221
227};
228
229
236inline LogStream &
237operator<<(LogStream &s, const BlockIndices &bi)
238{
239 const unsigned int n = bi.size();
240 s << n << ":[";
241 // Write first size without leading space
242 if (n > 0)
243 s << bi.block_size(0);
244 // Write all other sizes
245 for (unsigned int i = 1; i < n; ++i)
246 s << ' ' << bi.block_size(i);
247 s << "]->" << bi.total_size();
248 return s;
249}
250
251
252
253/* ---------------------- template and inline functions ------------------- */
254
255inline void
256BlockIndices::reinit(const unsigned int nb, const size_type block_size)
257{
258 n_blocks = nb;
259 start_indices.resize(n_blocks + 1);
260 for (size_type i = 0; i <= n_blocks; ++i)
261 start_indices[i] = i * block_size;
262}
263
264
265
266inline void
267BlockIndices::reinit(const std::vector<size_type> &block_sizes)
268{
269 if (start_indices.size() != block_sizes.size() + 1)
270 {
271 n_blocks = static_cast<unsigned int>(block_sizes.size());
272 start_indices.resize(n_blocks + 1);
273 }
274 start_indices[0] = 0;
275 for (size_type i = 1; i <= n_blocks; ++i)
276 start_indices[i] = start_indices[i - 1] + block_sizes[i - 1];
277}
278
279
281 : n_blocks(0)
282 , start_indices(1, 0)
283{}
284
285
286
287inline BlockIndices::BlockIndices(const unsigned int n_blocks,
288 const size_type block_size)
289 : n_blocks(n_blocks)
290 , start_indices(n_blocks + 1)
291{
292 for (size_type i = 0; i <= n_blocks; ++i)
293 start_indices[i] = i * block_size;
294}
295
296
297
298inline BlockIndices::BlockIndices(const std::vector<size_type> &block_sizes)
299 : n_blocks(static_cast<unsigned int>(block_sizes.size()))
300 , start_indices(block_sizes.size() + 1)
301{
302 reinit(block_sizes);
303}
304
305
306
308 : n_blocks(b.n_blocks)
309 , start_indices(std::move(b.start_indices))
310{
311 b.n_blocks = 0;
312 b.start_indices = std::vector<size_type>(1, 0);
313}
314
315
316
317inline void
319{
320 start_indices.push_back(start_indices[n_blocks] + sz);
321 ++n_blocks;
323}
324
325
326inline std::pair<unsigned int, BlockIndices::size_type>
328{
330 Assert(n_blocks > 0, ExcLowerRangeType<size_type>(i, size_type(1)));
331
332 // start_indices[0] == 0 so we might as well start from the next one
333 const auto it = std::prev(
334 std::upper_bound(std::next(start_indices.begin()), start_indices.end(), i));
335
336 return {std::distance(start_indices.begin(), it), i - *it};
337}
338
339
341BlockIndices::local_to_global(const unsigned int block,
342 const size_type index) const
343{
345 AssertIndexRange(index, start_indices[block + 1] - start_indices[block]);
346
347 return start_indices[block] + index;
348}
349
350
351inline unsigned int
353{
354 return n_blocks;
355}
356
357
358
361{
362 if (n_blocks == 0)
363 return 0;
364 return start_indices[n_blocks];
365}
366
367
368
370BlockIndices::block_size(const unsigned int block) const
371{
373 return start_indices[block + 1] - start_indices[block];
374}
375
376
377
378inline std::string
380{
381 std::string result = "[" + std::to_string(n_blocks) + "->";
382 for (unsigned int i = 0; i < n_blocks; ++i)
383 {
384 if (i > 0)
385 result += ',';
386 result += std::to_string(block_size(i));
387 }
388 result += "|" + std::to_string(total_size()) + ']';
389 return result;
390}
391
392
393
395BlockIndices::block_start(const unsigned int block) const
396{
398 return start_indices[block];
399}
400
401
402
403inline BlockIndices &
405{
406 start_indices = b.start_indices;
407 n_blocks = b.n_blocks;
408 return *this;
409}
410
411
412
413inline BlockIndices &
415{
416 start_indices = std::move(b.start_indices);
417 n_blocks = b.n_blocks;
418
419 b.start_indices = std::vector<size_type>(1, 0);
420 b.n_blocks = 0;
421
422 return *this;
423}
424
425
426
427inline bool
429{
430 if (n_blocks != b.n_blocks)
431 return false;
432
433 for (size_type i = 0; i <= n_blocks; ++i)
434 if (start_indices[i] != b.start_indices[i])
435 return false;
436
437 return true;
438}
439
440
441
442inline void
444{
445 std::swap(n_blocks, b.n_blocks);
446 std::swap(start_indices, b.start_indices);
447}
448
449
450
451inline std::size_t
453{
454 return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
455}
456
457
458
459/* ----------------- global functions ---------------------------- */
460
461
469inline void
471{
472 u.swap(v);
473}
474
475
476
478
479#endif
std::string to_string() const
void swap(BlockIndices &u, BlockIndices &v) noexcept
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)
void swap(BlockIndices &b) noexcept
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
size_type block_start(const unsigned int i) const
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:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
std::size_t size
Definition mpi.cc:733
STL namespace.
unsigned int global_dof_index
Definition types.h:92