deal.II version GIT relicensing-2206-gaa53ff9447 2024-12-02 09:10:00+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: LGPL-2.1-or-later
4// Copyright (C) 2000 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_block_indices_h
16#define dealii_block_indices_h
17
18
19#include <deal.II/base/config.h>
20
24
25#include <algorithm>
26#include <cstddef>
27#include <string>
28#include <vector>
29
31
32
60{
61public:
66
71
77 BlockIndices(const std::vector<size_type> &block_sizes);
78
83 BlockIndices(BlockIndices &&b) noexcept;
84
88 BlockIndices(const BlockIndices &) = default;
89
93 explicit BlockIndices(const unsigned int n_blocks,
94 const size_type block_size = 0);
95
100 void
101 reinit(const unsigned int n_blocks, const size_type n_elements_per_block);
102
109 void
110 reinit(const std::vector<size_type> &block_sizes);
111
115 void
116 push_back(const size_type size);
117
126 unsigned int
127 size() const;
128
134 total_size() const;
135
140 block_size(const unsigned int i) const;
141
147 std::string
148 to_string() const;
149
167 std::pair<unsigned int, size_type>
168 global_to_local(const size_type i) const;
169
174 local_to_global(const unsigned int block, const size_type index) const;
175
180 block_start(const unsigned int i) const;
187 operator=(const BlockIndices &b);
188
194 operator=(BlockIndices &&) noexcept;
195
200 bool
201 operator==(const BlockIndices &b) const;
202
206 void
207 swap(BlockIndices &b) noexcept;
208
213 std::size_t
214 memory_consumption() const;
215
216private:
221 unsigned int n_blocks;
222
228};
229
230
237inline LogStream &
238operator<<(LogStream &s, const BlockIndices &bi)
239{
240 const unsigned int n = bi.size();
241 s << n << ":[";
242 // Write first size without leading space
243 if (n > 0)
244 s << bi.block_size(0);
245 // Write all other sizes
246 for (unsigned int i = 1; i < n; ++i)
247 s << ' ' << bi.block_size(i);
248 s << "]->" << bi.total_size();
249 return s;
250}
251
252
253
254/* ---------------------- template and inline functions ------------------- */
255
256inline void
257BlockIndices::reinit(const unsigned int nb, const size_type block_size)
258{
259 n_blocks = nb;
260 start_indices.resize(n_blocks + 1);
261 for (size_type i = 0; i <= n_blocks; ++i)
262 start_indices[i] = i * block_size;
263}
264
265
266
267inline void
268BlockIndices::reinit(const std::vector<size_type> &block_sizes)
269{
270 if (start_indices.size() != block_sizes.size() + 1)
271 {
272 n_blocks = static_cast<unsigned int>(block_sizes.size());
273 start_indices.resize(n_blocks + 1);
274 }
275 start_indices[0] = 0;
276 for (size_type i = 1; i <= n_blocks; ++i)
277 start_indices[i] = start_indices[i - 1] + block_sizes[i - 1];
278}
279
280
282 : n_blocks(0)
283 , start_indices(1, 0)
284{}
285
286
287
288inline BlockIndices::BlockIndices(const unsigned int n_blocks,
289 const size_type block_size)
290 : n_blocks(n_blocks)
291 , start_indices(n_blocks + 1)
292{
293 for (size_type i = 0; i <= n_blocks; ++i)
294 start_indices[i] = i * block_size;
295}
296
297
298
299inline BlockIndices::BlockIndices(const std::vector<size_type> &block_sizes)
300 : n_blocks(static_cast<unsigned int>(block_sizes.size()))
301 , start_indices(block_sizes.size() + 1)
302{
303 reinit(block_sizes);
304}
305
306
307
309 : n_blocks(b.n_blocks)
310 , start_indices(std::move(b.start_indices))
311{
312 b.n_blocks = 0;
313 b.start_indices = std::vector<size_type>(1, 0);
314}
315
316
317
318inline void
320{
321 start_indices.push_back(start_indices[n_blocks] + sz);
322 ++n_blocks;
324}
325
326
327inline std::pair<unsigned int, BlockIndices::size_type>
329{
331 Assert(n_blocks > 0, ExcLowerRangeType<size_type>(i, size_type(1)));
332
333 // start_indices[0] == 0 so we might as well start from the next one
334 const auto it = std::prev(
335 std::upper_bound(std::next(start_indices.begin()), start_indices.end(), i));
336
337 return {std::distance(start_indices.begin(), it), i - *it};
338}
339
340
342BlockIndices::local_to_global(const unsigned int block,
343 const size_type index) const
344{
346 AssertIndexRange(index, start_indices[block + 1] - start_indices[block]);
347
348 return start_indices[block] + index;
349}
350
351
352inline unsigned int
354{
355 return n_blocks;
356}
357
358
359
362{
363 if (n_blocks == 0)
364 return 0;
365 return start_indices[n_blocks];
366}
367
368
369
371BlockIndices::block_size(const unsigned int block) const
372{
374 return start_indices[block + 1] - start_indices[block];
375}
376
377
378
379inline std::string
381{
382 std::string result = "[" + std::to_string(n_blocks) + "->";
383 for (unsigned int i = 0; i < n_blocks; ++i)
384 {
385 if (i > 0)
386 result += ',';
387 result += std::to_string(block_size(i));
388 }
389 result += "|" + std::to_string(total_size()) + ']';
390 return result;
391}
392
393
394
396BlockIndices::block_start(const unsigned int block) const
397{
399 return start_indices[block];
400}
401
402
403
404inline BlockIndices &
406{
407 start_indices = b.start_indices;
408 n_blocks = b.n_blocks;
409 return *this;
410}
411
412
413
414inline BlockIndices &
416{
417 start_indices = std::move(b.start_indices);
418 n_blocks = b.n_blocks;
419
420 b.start_indices = std::vector<size_type>(1, 0);
421 b.n_blocks = 0;
422
423 return *this;
424}
425
426
427
428inline bool
430{
431 if (n_blocks != b.n_blocks)
432 return false;
433
434 for (size_type i = 0; i <= n_blocks; ++i)
435 if (start_indices[i] != b.start_indices[i])
436 return false;
437
438 return true;
439}
440
441
442
443inline void
445{
446 std::swap(n_blocks, b.n_blocks);
447 std::swap(start_indices, b.start_indices);
448}
449
450
451
452inline std::size_t
454{
455 return (sizeof(*this) + start_indices.size() * sizeof(start_indices[0]));
456}
457
458
459
460/* ----------------- global functions ---------------------------- */
461
462
470inline void
472{
473 u.swap(v);
474}
475
476
477
479
480#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:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
std::size_t size
Definition mpi.cc:734
STL namespace.
unsigned int global_dof_index
Definition types.h:81