deal.II version 9.7.0
\(\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_sparsity_pattern.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: 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// 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
17
19
21
22
23template <typename SparsityPatternType>
28
29
30
31template <typename SparsityPatternType>
39
40
41
42template <typename SparsityPatternType>
46{
47 Assert(s.n_block_rows() == 0 && s.n_block_cols() == 0,
49 "This constructor can only be called if the provided argument "
50 "is the sparsity pattern for an empty matrix. This constructor can "
51 "not be used to copy-construct a non-empty sparsity pattern."));
52}
53
54
55
56template <typename SparsityPatternType>
57void
59 const size_type new_block_rows,
60 const size_type new_block_columns)
61{
62 sub_objects.reinit(0, 0);
63
64 block_rows = new_block_rows;
65 block_columns = new_block_columns;
66
68 for (size_type i = 0; i < n_block_rows(); ++i)
69 for (size_type j = 0; j < n_block_cols(); ++j)
70 sub_objects[i][j] = std::make_unique<SparsityPatternType>();
71}
72
73
74template <typename SparsityPatternType>
78{
81 // copy objects
82 for (size_type i = 0; i < n_block_rows(); ++i)
83 for (size_type j = 0; j < n_block_cols(); ++j)
84 *sub_objects[i][j] = *bsp.sub_objects[i][j];
85 // update index objects
87
88 return *this;
89}
90
91
92
93template <typename SparsityPatternType>
96{
97 // only count in first column, since
98 // all rows should be equivalent
99 size_type count = 0;
100 for (size_type r = 0; r < n_block_rows(); ++r)
101 count += sub_objects[r][0]->n_rows();
102 return count;
103}
104
105
106
107template <typename SparsityPatternType>
110{
111 // only count in first row, since
112 // all rows should be equivalent
113 size_type count = 0;
114 for (size_type c = 0; c < n_block_cols(); ++c)
115 count += sub_objects[0][c]->n_cols();
116 return count;
117}
118
119
120
121template <typename SparsityPatternType>
122void
124{
126
127 std::vector<size_type> row_sizes(n_block_rows());
128 std::vector<size_type> col_sizes(n_block_cols());
129
130 // first find out the row sizes
131 // from the first block column
132 for (size_type r = 0; r < n_block_rows(); ++r)
133 row_sizes[r] = sub_objects[r][0]->n_rows();
134 // then check that the following
135 // block columns have the same
136 // sizes
137 for (size_type c = 1; c < n_block_cols(); ++c)
138 for (size_type r = 0; r < n_block_rows(); ++r)
139 Assert(row_sizes[r] == sub_objects[r][c]->n_rows(),
140 ExcIncompatibleRowNumbers(r, 0, r, c));
141
142 // finally initialize the row
143 // indices with this array
144 row_indices.reinit(row_sizes);
145
146
147 // then do the same with the columns
148 for (size_type c = 0; c < n_block_cols(); ++c)
149 col_sizes[c] = sub_objects[0][c]->n_cols();
150 for (size_type r = 1; r < n_block_rows(); ++r)
151 for (size_type c = 0; c < n_block_cols(); ++c)
152 Assert(col_sizes[c] == sub_objects[r][c]->n_cols(),
153 ExcIncompatibleRowNumbers(0, c, r, c));
154
155 // finally initialize the row
156 // indices with this array
157 column_indices.reinit(col_sizes);
158
159 // Resize scratch arrays
162}
163
164
165
166template <typename SparsityPatternType>
167void
169{
170 for (size_type i = 0; i < n_block_rows(); ++i)
171 for (size_type j = 0; j < n_block_cols(); ++j)
172 sub_objects[i][j]->compress();
173}
174
175
176
177template <typename SparsityPatternType>
178bool
180{
181 for (size_type i = 0; i < n_block_rows(); ++i)
182 for (size_type j = 0; j < n_block_cols(); ++j)
183 if (sub_objects[i][j]->empty() == false)
184 return false;
185 return true;
186}
187
188
189
190template <typename SparsityPatternType>
193{
194 size_type max_entries = 0;
195 for (size_type block_row = 0; block_row < n_block_rows(); ++block_row)
196 {
197 size_type this_row = 0;
198 for (size_type c = 0; c < n_block_cols(); ++c)
199 this_row += sub_objects[block_row][c]->max_entries_per_row();
200
201 if (this_row > max_entries)
202 max_entries = this_row;
203 }
204 return max_entries;
205}
207
208
209template <typename SparsityPatternType>
212{
213 size_type count = 0;
214 for (size_type i = 0; i < n_block_rows(); ++i)
215 for (size_type j = 0; j < n_block_cols(); ++j)
216 count += sub_objects[i][j]->n_nonzero_elements();
217 return count;
218}
219
220
221
222template <typename SparsityPatternType>
223void
225{
226 size_type k = 0;
227 for (size_type ib = 0; ib < n_block_rows(); ++ib)
228 {
229 for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
230 {
231 out << '[' << i + k;
232 size_type l = 0;
233 for (size_type jb = 0; jb < n_block_cols(); ++jb)
234 {
235 const SparsityPatternType &b = block(ib, jb);
236 for (size_type j = 0; j < b.n_cols(); ++j)
237 if (b.exists(i, j))
238 out << ',' << l + j;
239 l += b.n_cols();
240 }
241 out << ']' << std::endl;
242 }
243 k += block(ib, 0).n_rows();
244 }
245}
246
247
248#ifndef DOXYGEN
249template <>
250void
252{
253 size_type k = 0;
254 for (size_type ib = 0; ib < n_block_rows(); ++ib)
255 {
256 for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
257 {
258 out << '[' << i + k;
259 size_type l = 0;
260 for (size_type jb = 0; jb < n_block_cols(); ++jb)
261 {
262 const DynamicSparsityPattern &b = block(ib, jb);
263 if (b.row_index_set().size() == 0 ||
264 b.row_index_set().is_element(i))
265 for (size_type j = 0; j < b.n_cols(); ++j)
266 if (b.exists(i, j))
267 out << ',' << l + j;
268 l += b.n_cols();
269 }
270 out << ']' << std::endl;
271 }
272 k += block(ib, 0).n_rows();
273 }
274}
275#endif
276
277
278
279template <typename SparsityPatternType>
280void
282 std::ostream &out) const
283{
284 size_type k = 0;
285 for (size_type ib = 0; ib < n_block_rows(); ++ib)
286 {
287 for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
288 {
289 size_type l = 0;
290 for (size_type jb = 0; jb < n_block_cols(); ++jb)
291 {
292 const SparsityPatternType &b = block(ib, jb);
293 for (size_type j = 0; j < b.n_cols(); ++j)
294 if (b.exists(i, j))
295 out << l + j << " " << -static_cast<signed int>(i + k)
296 << std::endl;
297 l += b.n_cols();
298 }
299 }
300 k += block(ib, 0).n_rows();
301 }
302}
304
305
306template <typename SparsityPatternType>
307void
309 std::ostream &out) const
310{
311 const unsigned int m = this->n_rows();
312 const unsigned int n = this->n_cols();
313 out
314 << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 "
315 << n + 2 << " " << m + 2
316 << " \">\n"
317 "<style type=\"text/css\" >\n"
318 " <![CDATA[\n"
319 " rect.pixel {\n"
320 " fill: #ff0000;\n"
321 " }\n"
322 " ]]>\n"
323 " </style>\n\n"
324 " <rect width=\""
325 << n + 2 << "\" height=\"" << m + 2
326 << "\" fill=\"rgb(128, 128, 128)\"/>\n"
327 " <rect x=\"1\" y=\"1\" width=\""
328 << n + 0.1 << "\" height=\"" << m + 0.1
329 << "\" fill=\"rgb(255, 255, 255)\"/>\n\n";
330
331 for (unsigned int block_i = 0; block_i < n_block_rows(); ++block_i)
332 for (unsigned int block_j = 0; block_j < n_block_cols(); ++block_j)
333 for (const auto &entry : block(block_i, block_j))
334 {
335 out << " <rect class=\"pixel\" x=\""
336 << column_indices.local_to_global(block_j, entry.column()) + 1
337 << "\" y=\""
338 << row_indices.local_to_global(block_i, entry.row()) + 1
339 << "\" width=\".9\" height=\".9\"/>\n";
340 }
341
342 out << "</svg>" << std::endl;
343}
344
345
346
347template <typename SparsityPatternType>
348std::size_t
363
364
365
370
371
372void
374 const BlockIndices &rows,
375 const BlockIndices &cols,
376 const std::vector<std::vector<unsigned int>> &row_lengths)
377{
378 AssertDimension(row_lengths.size(), cols.size());
379
380 this->reinit(rows.size(), cols.size());
381 for (size_type j = 0; j < cols.size(); ++j)
382 for (size_type i = 0; i < rows.size(); ++i)
383 {
384 const size_type start = rows.local_to_global(i, 0);
385 const size_type length = rows.block_size(i);
386
387 if (row_lengths[j].size() == 1)
388 block(i, j).reinit(rows.block_size(i),
389 cols.block_size(j),
390 row_lengths[j][0]);
391 else
392 {
393 Assert(row_lengths[j].begin() + start + length <=
394 row_lengths[j].end(),
396 ArrayView<const unsigned int> block_rows(row_lengths[j].data() +
397 start,
398 length);
399 block(i, j).reinit(rows.block_size(i),
400 cols.block_size(j),
401 block_rows);
402 }
403 }
404 this->collect_sizes();
407}
408
409
410bool
412{
413 for (size_type i = 0; i < n_block_rows(); ++i)
414 for (size_type j = 0; j < n_block_cols(); ++j)
415 if (sub_objects[i][j]->is_compressed() == false)
416 return false;
417 return true;
418}
419
420
421
422void
424{
425 // delete old content, set block
426 // sizes anew
427 reinit(dsp.n_block_rows(), dsp.n_block_cols());
428
429 // copy over blocks
430 for (size_type i = 0; i < n_block_rows(); ++i)
431 for (size_type j = 0; j < n_block_cols(); ++j)
432 block(i, j).copy_from(dsp.block(i, j));
433
434 // and finally enquire their new
435 // sizes
437}
438
439
440
446
447
448
450 const std::vector<size_type> &row_indices,
451 const std::vector<size_type> &col_indices)
453 col_indices.size())
454{
455 for (size_type i = 0; i < row_indices.size(); ++i)
456 for (size_type j = 0; j < col_indices.size(); ++j)
457 this->block(i, j).reinit(row_indices[i], col_indices[j]);
458 this->collect_sizes();
459}
460
461
462
464 const std::vector<IndexSet> &partitioning)
466 partitioning.size())
467{
468 for (size_type i = 0; i < partitioning.size(); ++i)
469 for (size_type j = 0; j < partitioning.size(); ++j)
470 this->block(i, j).reinit(partitioning[i].size(),
471 partitioning[j].size(),
472 partitioning[i]);
473 this->collect_sizes();
474}
475
476
477
484
485
486
487void
489 const std::vector<size_type> &row_block_sizes,
490 const std::vector<size_type> &col_block_sizes)
491{
493 row_block_sizes.size(), col_block_sizes.size());
494 for (size_type i = 0; i < row_block_sizes.size(); ++i)
495 for (size_type j = 0; j < col_block_sizes.size(); ++j)
496 this->block(i, j).reinit(row_block_sizes[i], col_block_sizes[j]);
497 this->collect_sizes();
498}
499
500
501
502void
503BlockDynamicSparsityPattern::reinit(const std::vector<IndexSet> &partitioning)
504{
506 partitioning.size());
507 for (size_type i = 0; i < partitioning.size(); ++i)
508 for (size_type j = 0; j < partitioning.size(); ++j)
509 this->block(i, j).reinit(partitioning[i].size(),
510 partitioning[j].size(),
511 partitioning[i]);
512 this->collect_sizes();
513}
514
515
516
517void
519 const BlockIndices &col_indices)
520{
522 col_indices.size());
523 for (size_type i = 0; i < row_indices.size(); ++i)
524 for (size_type j = 0; j < col_indices.size(); ++j)
525 this->block(i, j).reinit(row_indices.block_size(i),
526 col_indices.block_size(j));
527 this->collect_sizes();
528}
529
530
531#ifdef DEAL_II_WITH_TRILINOS
532namespace TrilinosWrappers
533{
538
539
540
542 const std::vector<size_type> &row_indices,
543 const std::vector<size_type> &col_indices)
545 col_indices.size())
546 {
547 for (size_type i = 0; i < row_indices.size(); ++i)
548 for (size_type j = 0; j < col_indices.size(); ++j)
549 this->block(i, j).reinit(row_indices[i], col_indices[j]);
550 this->collect_sizes();
551 }
552
553
554
556 const std::vector<IndexSet> &parallel_partitioning,
557 const MPI_Comm communicator)
558 : BlockSparsityPatternBase<SparsityPattern>(parallel_partitioning.size(),
559 parallel_partitioning.size())
560 {
561 for (size_type i = 0; i < parallel_partitioning.size(); ++i)
562 for (size_type j = 0; j < parallel_partitioning.size(); ++j)
563 this->block(i, j).reinit(parallel_partitioning[i],
564 parallel_partitioning[j],
565 communicator);
566 this->collect_sizes();
567 }
568
569
570
572 const std::vector<IndexSet> &row_parallel_partitioning,
573 const std::vector<IndexSet> &col_parallel_partitioning,
574 const std::vector<IndexSet> &writable_rows,
575 const MPI_Comm communicator)
577 row_parallel_partitioning.size(),
578 col_parallel_partitioning.size())
579 {
580 for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
581 for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
582 this->block(i, j).reinit(row_parallel_partitioning[i],
583 col_parallel_partitioning[j],
584 writable_rows[i],
585 communicator);
586 this->collect_sizes();
587 }
588
589
590
591 void
592 BlockSparsityPattern::reinit(const std::vector<size_type> &row_block_sizes,
593 const std::vector<size_type> &col_block_sizes)
594 {
596 row_block_sizes.size(), col_block_sizes.size());
597 for (size_type i = 0; i < row_block_sizes.size(); ++i)
598 for (size_type j = 0; j < col_block_sizes.size(); ++j)
599 this->block(i, j).reinit(row_block_sizes[i], col_block_sizes[j]);
600 this->collect_sizes();
601 }
602
603
604
605 void
607 const std::vector<IndexSet> &parallel_partitioning,
608 const MPI_Comm communicator)
609 {
611 parallel_partitioning.size(), parallel_partitioning.size());
612 for (size_type i = 0; i < parallel_partitioning.size(); ++i)
613 for (size_type j = 0; j < parallel_partitioning.size(); ++j)
614 this->block(i, j).reinit(parallel_partitioning[i],
615 parallel_partitioning[j],
616 communicator);
617 this->collect_sizes();
618 }
619
620
621
622 void
624 const std::vector<IndexSet> &row_parallel_partitioning,
625 const std::vector<IndexSet> &col_parallel_partitioning,
626 const MPI_Comm communicator)
627 {
629 row_parallel_partitioning.size(), col_parallel_partitioning.size());
630 for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
631 for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
632 this->block(i, j).reinit(row_parallel_partitioning[i],
633 col_parallel_partitioning[j],
634 communicator);
635 this->collect_sizes();
636 }
637
638
639
640 void
642 const std::vector<IndexSet> &row_parallel_partitioning,
643 const std::vector<IndexSet> &col_parallel_partitioning,
644 const std::vector<IndexSet> &writable_rows,
645 const MPI_Comm communicator)
646 {
647 AssertDimension(writable_rows.size(), row_parallel_partitioning.size());
649 row_parallel_partitioning.size(), col_parallel_partitioning.size());
650 for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
651 for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
652 this->block(i, j).reinit(row_parallel_partitioning[i],
653 col_parallel_partitioning[j],
654 writable_rows[i],
655 communicator);
656 this->collect_sizes();
657 }
658
659} // namespace TrilinosWrappers
660
661#endif
662
665#ifdef DEAL_II_WITH_TRILINOS
667#endif
668
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
size_type block_size(const unsigned int i) const
unsigned int size() const
void print_gnuplot(std::ostream &out) const
Table< 2, std::unique_ptr< SparsityPatternType > > sub_objects
SparsityPatternType & block(const size_type row, const size_type column)
types::global_dof_index size_type
std::vector< std::vector< size_type > > block_column_indices
size_type n_rows() const
void print(std::ostream &out) const
std::size_t memory_consumption() const
void print_svg(std::ostream &out) const
void reinit(const size_type n_block_rows, const size_type n_block_columns)
BlockSparsityPatternBase & operator=(const BlockSparsityPatternBase &)
size_type n_cols() const
void copy_from(const BlockDynamicSparsityPattern &dsp)
void reinit(const size_type n_block_rows, const size_type n_block_columns)
BlockSparsityPattern()=default
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
virtual void resize(const size_type rows, const size_type cols)
void reinit(const size_type m, const size_type n, const ArrayView< const unsigned int > &row_lengths)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
static ::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)