Reference documentation for deal.II version 9.1.0-pre
block_sparsity_pattern.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2017 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 
17 #include <deal.II/base/memory_consumption.h>
18 #include <deal.II/base/vector_slice.h>
19 
20 #include <deal.II/lac/block_sparsity_pattern.h>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 
25 template <class SparsityPatternBase>
27  : rows(0)
28  , columns(0)
29 {}
30 
31 
32 
33 template <class SparsityPatternBase>
35  const size_type n_block_rows,
36  const size_type n_block_columns)
37  : rows(0)
38  , columns(0)
39 {
40  reinit(n_block_rows, n_block_columns);
41 }
42 
43 
44 
45 template <class SparsityPatternBase>
47  const BlockSparsityPatternBase &s)
48  : Subscriptor()
49  , rows(0)
50  , columns(0)
51 {
52  (void)s;
53  Assert(s.rows == 0 && s.columns == 0,
54  ExcMessage(
55  "This constructor can only be called if the provided argument "
56  "is the sparsity pattern for an empty matrix. This constructor can "
57  "not be used to copy-construct a non-empty sparsity pattern."));
58 }
59 
60 
61 
62 template <class SparsityPatternBase>
64 {
65  // clear all memory
66  try
67  {
68  reinit(0, 0);
69  }
70  catch (...)
71  {}
72 }
73 
74 
75 
76 template <class SparsityPatternBase>
77 void
79  const size_type n_block_rows,
80  const size_type n_block_columns)
81 {
82  // delete previous content and
83  // clean the sub_objects array
84  // completely
85  for (size_type i = 0; i < rows; ++i)
86  for (size_type j = 0; j < columns; ++j)
87  {
88  SparsityPatternBase *sp = sub_objects[i][j];
89  sub_objects[i][j] = nullptr;
90  delete sp;
91  };
92  sub_objects.reinit(0, 0);
93 
94  // then set new sizes
95  rows = n_block_rows;
96  columns = n_block_columns;
97  sub_objects.reinit(rows, columns);
98 
99  // allocate new objects
100  for (size_type i = 0; i < rows; ++i)
101  for (size_type j = 0; j < columns; ++j)
102  {
103  SparsityPatternBase *p = new SparsityPatternBase;
104  sub_objects[i][j] = p;
105  }
106 }
107 
108 
109 template <class SparsityPatternBase>
113 {
114  Assert(rows == bsp.rows, ExcDimensionMismatch(rows, bsp.rows));
116  // copy objects
117  for (size_type i = 0; i < rows; ++i)
118  for (size_type j = 0; j < columns; ++j)
119  *sub_objects[i][j] = *bsp.sub_objects[i][j];
120  // update index objects
121  collect_sizes();
122 
123  return *this;
124 }
125 
126 
127 
128 template <class SparsityPatternBase>
129 void
131 {
132  std::vector<size_type> row_sizes(rows);
133  std::vector<size_type> col_sizes(columns);
134 
135  // first find out the row sizes
136  // from the first block column
137  for (size_type r = 0; r < rows; ++r)
138  row_sizes[r] = sub_objects[r][0]->n_rows();
139  // then check that the following
140  // block columns have the same
141  // sizes
142  for (size_type c = 1; c < columns; ++c)
143  for (size_type r = 0; r < rows; ++r)
144  Assert(row_sizes[r] == sub_objects[r][c]->n_rows(),
145  ExcIncompatibleRowNumbers(r, 0, r, c));
146 
147  // finally initialize the row
148  // indices with this array
149  row_indices.reinit(row_sizes);
150 
151 
152  // then do the same with the columns
153  for (size_type c = 0; c < columns; ++c)
154  col_sizes[c] = sub_objects[0][c]->n_cols();
155  for (size_type r = 1; r < rows; ++r)
156  for (size_type c = 0; c < columns; ++c)
157  Assert(col_sizes[c] == sub_objects[r][c]->n_cols(),
158  ExcIncompatibleRowNumbers(0, c, r, c));
159 
160  // finally initialize the row
161  // indices with this array
162  column_indices.reinit(col_sizes);
163 }
164 
165 
166 
167 template <class SparsityPatternBase>
168 void
170 {
171  for (size_type i = 0; i < rows; ++i)
172  for (size_type j = 0; j < columns; ++j)
173  sub_objects[i][j]->compress();
174 }
175 
176 
177 
178 template <class SparsityPatternBase>
179 bool
181 {
182  for (size_type i = 0; i < rows; ++i)
183  for (size_type j = 0; j < columns; ++j)
184  if (sub_objects[i][j]->empty() == false)
185  return false;
186  return true;
187 }
188 
189 
190 
191 template <class SparsityPatternBase>
194 {
195  size_type max_entries = 0;
196  for (size_type block_row = 0; block_row < rows; ++block_row)
197  {
198  size_type this_row = 0;
199  for (size_type c = 0; c < columns; ++c)
200  this_row += sub_objects[block_row][c]->max_entries_per_row();
201 
202  if (this_row > max_entries)
203  max_entries = this_row;
204  };
205  return max_entries;
206 }
207 
208 
209 
210 template <class SparsityPatternBase>
213 {
214  // only count in first column, since
215  // all rows should be equivalent
216  size_type count = 0;
217  for (size_type r = 0; r < rows; ++r)
218  count += sub_objects[r][0]->n_rows();
219  return count;
220 }
221 
222 
223 
224 template <class SparsityPatternBase>
227 {
228  // only count in first row, since
229  // all rows should be equivalent
230  size_type count = 0;
231  for (size_type c = 0; c < columns; ++c)
232  count += sub_objects[0][c]->n_cols();
233  return count;
234 }
235 
236 
237 
238 template <class SparsityPatternBase>
241 {
242  size_type count = 0;
243  for (size_type i = 0; i < rows; ++i)
244  for (size_type j = 0; j < columns; ++j)
245  count += sub_objects[i][j]->n_nonzero_elements();
246  return count;
247 }
248 
249 
250 
251 template <class SparsityPatternBase>
252 void
254 {
255  size_type k = 0;
256  for (size_type ib = 0; ib < n_block_rows(); ++ib)
257  {
258  for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
259  {
260  out << '[' << i + k;
261  size_type l = 0;
262  for (size_type jb = 0; jb < n_block_cols(); ++jb)
263  {
264  const SparsityPatternBase &b = block(ib, jb);
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 
276 
277 template <>
278 void
280 {
281  size_type k = 0;
282  for (size_type ib = 0; ib < n_block_rows(); ++ib)
283  {
284  for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
285  {
286  out << '[' << i + k;
287  size_type l = 0;
288  for (size_type jb = 0; jb < n_block_cols(); ++jb)
289  {
290  const DynamicSparsityPattern &b = block(ib, jb);
291  if (b.row_index_set().size() == 0 ||
292  b.row_index_set().is_element(i))
293  for (size_type j = 0; j < b.n_cols(); ++j)
294  if (b.exists(i, j))
295  out << ',' << l + j;
296  l += b.n_cols();
297  }
298  out << ']' << std::endl;
299  }
300  k += block(ib, 0).n_rows();
301  }
302 }
303 
304 
305 template <class SparsityPatternBase>
306 void
308  std::ostream &out) const
309 {
310  size_type k = 0;
311  for (size_type ib = 0; ib < n_block_rows(); ++ib)
312  {
313  for (size_type i = 0; i < block(ib, 0).n_rows(); ++i)
314  {
315  size_type l = 0;
316  for (size_type jb = 0; jb < n_block_cols(); ++jb)
317  {
318  const SparsityPatternBase &b = block(ib, jb);
319  for (size_type j = 0; j < b.n_cols(); ++j)
320  if (b.exists(i, j))
321  out << l + j << " " << -static_cast<signed int>(i + k)
322  << std::endl;
323  l += b.n_cols();
324  }
325  }
326  k += block(ib, 0).n_rows();
327  }
328 }
329 
330 
331 
333  const size_type n_columns)
334  : BlockSparsityPatternBase<SparsityPattern>(n_rows, n_columns)
335 {}
336 
337 
338 void
340  const BlockIndices & rows,
341  const BlockIndices & cols,
342  const std::vector<std::vector<unsigned int>> &row_lengths)
343 {
344  AssertDimension(row_lengths.size(), cols.size());
345 
346  this->reinit(rows.size(), cols.size());
347  for (size_type j = 0; j < cols.size(); ++j)
348  for (size_type i = 0; i < rows.size(); ++i)
349  {
350  const size_type start = rows.local_to_global(i, 0);
351  const size_type length = rows.block_size(i);
352 
353  if (row_lengths[j].size() == 1)
354  block(i, j).reinit(rows.block_size(i),
355  cols.block_size(j),
356  row_lengths[j][0]);
357  else
358  {
360  row_lengths[j], start, length);
361  block(i, j).reinit(rows.block_size(i),
362  cols.block_size(j),
363  block_rows);
364  }
365  }
366  this->collect_sizes();
367  Assert(this->row_indices == rows, ExcInternalError());
368  Assert(this->column_indices == cols, ExcInternalError());
369 }
370 
371 
372 bool
374 {
375  for (size_type i = 0; i < rows; ++i)
376  for (size_type j = 0; j < columns; ++j)
377  if (sub_objects[i][j]->is_compressed() == false)
378  return false;
379  return true;
380 }
381 
382 
383 std::size_t
385 {
386  std::size_t mem = 0;
392  for (size_type r = 0; r < rows; ++r)
393  for (size_type c = 0; c < columns; ++c)
395 
396  return mem;
397 }
398 
399 
400 
401 void
403 {
404  // delete old content, set block
405  // sizes anew
406  reinit(dsp.n_block_rows(), dsp.n_block_cols());
407 
408  // copy over blocks
409  for (size_type i = 0; i < n_block_rows(); ++i)
410  for (size_type j = 0; j < n_block_cols(); ++j)
411  block(i, j).copy_from(dsp.block(i, j));
412 
413  // and finally enquire their new
414  // sizes
415  collect_sizes();
416 }
417 
418 
419 
421  const size_type n_rows,
422  const size_type n_columns)
424 {}
425 
426 
427 
429  const std::vector<size_type> &row_indices,
430  const std::vector<size_type> &col_indices)
431  : BlockSparsityPatternBase<DynamicSparsityPattern>(row_indices.size(),
432  col_indices.size())
433 {
434  for (size_type i = 0; i < row_indices.size(); ++i)
435  for (size_type j = 0; j < col_indices.size(); ++j)
436  this->block(i, j).reinit(row_indices[i], col_indices[j]);
437  this->collect_sizes();
438 }
439 
440 
442  const std::vector<IndexSet> &partitioning)
443  : BlockSparsityPatternBase<DynamicSparsityPattern>(partitioning.size(),
444  partitioning.size())
445 {
446  for (size_type i = 0; i < partitioning.size(); ++i)
447  for (size_type j = 0; j < partitioning.size(); ++j)
448  this->block(i, j).reinit(partitioning[i].size(),
449  partitioning[j].size(),
450  partitioning[i]);
451  this->collect_sizes();
452 }
453 
454 
456  const BlockIndices &row_indices,
457  const BlockIndices &col_indices)
458 {
459  reinit(row_indices, col_indices);
460 }
461 
462 
463 void
465  const std::vector<size_type> &row_block_sizes,
466  const std::vector<size_type> &col_block_sizes)
467 {
469  row_block_sizes.size(), col_block_sizes.size());
470  for (size_type i = 0; i < row_block_sizes.size(); ++i)
471  for (size_type j = 0; j < col_block_sizes.size(); ++j)
472  this->block(i, j).reinit(row_block_sizes[i], col_block_sizes[j]);
473  this->collect_sizes();
474 }
475 
476 void
477 BlockDynamicSparsityPattern::reinit(const std::vector<IndexSet> &partitioning)
478 {
480  partitioning.size());
481  for (size_type i = 0; i < partitioning.size(); ++i)
482  for (size_type j = 0; j < partitioning.size(); ++j)
483  this->block(i, j).reinit(partitioning[i].size(),
484  partitioning[j].size(),
485  partitioning[i]);
486  this->collect_sizes();
487 }
488 
489 void
491  const BlockIndices &col_indices)
492 {
494  col_indices.size());
495  for (size_type i = 0; i < row_indices.size(); ++i)
496  for (size_type j = 0; j < col_indices.size(); ++j)
497  this->block(i, j).reinit(row_indices.block_size(i),
498  col_indices.block_size(j));
499  this->collect_sizes();
500 }
501 
502 
503 #ifdef DEAL_II_WITH_TRILINOS
504 namespace TrilinosWrappers
505 {
507  const size_type n_columns)
508  : ::BlockSparsityPatternBase<SparsityPattern>(n_rows, n_columns)
509  {}
510 
511 
512 
514  const std::vector<size_type> &row_indices,
515  const std::vector<size_type> &col_indices)
516  : BlockSparsityPatternBase<SparsityPattern>(row_indices.size(),
517  col_indices.size())
518  {
519  for (size_type i = 0; i < row_indices.size(); ++i)
520  for (size_type j = 0; j < col_indices.size(); ++j)
521  this->block(i, j).reinit(row_indices[i], col_indices[j]);
522  this->collect_sizes();
523  }
524 
525 
526 
528  const std::vector<Epetra_Map> &parallel_partitioning)
529  : BlockSparsityPatternBase<SparsityPattern>(parallel_partitioning.size(),
530  parallel_partitioning.size())
531  {
532  for (size_type i = 0; i < parallel_partitioning.size(); ++i)
533  for (size_type j = 0; j < parallel_partitioning.size(); ++j)
534  this->block(i, j).reinit(parallel_partitioning[i],
535  parallel_partitioning[j]);
536  this->collect_sizes();
537  }
538 
539 
540 
542  const std::vector<IndexSet> &parallel_partitioning,
543  const MPI_Comm & communicator)
544  : BlockSparsityPatternBase<SparsityPattern>(parallel_partitioning.size(),
545  parallel_partitioning.size())
546  {
547  for (size_type i = 0; i < parallel_partitioning.size(); ++i)
548  for (size_type j = 0; j < parallel_partitioning.size(); ++j)
549  this->block(i, j).reinit(parallel_partitioning[i],
550  parallel_partitioning[j],
551  communicator);
552  this->collect_sizes();
553  }
554 
555 
556 
558  const std::vector<IndexSet> &row_parallel_partitioning,
559  const std::vector<IndexSet> &col_parallel_partitioning,
560  const std::vector<IndexSet> &writable_rows,
561  const MPI_Comm & communicator)
563  row_parallel_partitioning.size(),
564  col_parallel_partitioning.size())
565  {
566  for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
567  for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
568  this->block(i, j).reinit(row_parallel_partitioning[i],
569  col_parallel_partitioning[j],
570  writable_rows[i],
571  communicator);
572  this->collect_sizes();
573  }
574 
575 
576 
577  void
578  BlockSparsityPattern::reinit(const std::vector<size_type> &row_block_sizes,
579  const std::vector<size_type> &col_block_sizes)
580  {
582  row_block_sizes.size(), col_block_sizes.size());
583  for (size_type i = 0; i < row_block_sizes.size(); ++i)
584  for (size_type j = 0; j < col_block_sizes.size(); ++j)
585  this->block(i, j).reinit(row_block_sizes[i], col_block_sizes[j]);
586  this->collect_sizes();
587  }
588 
589 
590 
591  void
593  const std::vector<Epetra_Map> &parallel_partitioning)
594  {
596  parallel_partitioning.size(), parallel_partitioning.size());
597  for (size_type i = 0; i < parallel_partitioning.size(); ++i)
598  for (size_type j = 0; j < parallel_partitioning.size(); ++j)
599  this->block(i, j).reinit(parallel_partitioning[i],
600  parallel_partitioning[j]);
601  this->collect_sizes();
602  }
603 
604 
605 
606  void
608  const std::vector<IndexSet> &parallel_partitioning,
609  const MPI_Comm & communicator)
610  {
612  parallel_partitioning.size(), parallel_partitioning.size());
613  for (size_type i = 0; i < parallel_partitioning.size(); ++i)
614  for (size_type j = 0; j < parallel_partitioning.size(); ++j)
615  this->block(i, j).reinit(parallel_partitioning[i],
616  parallel_partitioning[j],
617  communicator);
618  this->collect_sizes();
619  }
620 
621 
622 
623  void
625  const std::vector<IndexSet> &row_parallel_partitioning,
626  const std::vector<IndexSet> &col_parallel_partitioning,
627  const MPI_Comm & communicator)
628  {
630  row_parallel_partitioning.size(), col_parallel_partitioning.size());
631  for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
632  for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
633  this->block(i, j).reinit(row_parallel_partitioning[i],
634  col_parallel_partitioning[j],
635  communicator);
636  this->collect_sizes();
637  }
638 
639 
640 
641  void
643  const std::vector<IndexSet> &row_parallel_partitioning,
644  const std::vector<IndexSet> &col_parallel_partitioning,
645  const std::vector<IndexSet> &writable_rows,
646  const MPI_Comm & communicator)
647  {
648  AssertDimension(writable_rows.size(), row_parallel_partitioning.size());
650  row_parallel_partitioning.size(), col_parallel_partitioning.size());
651  for (size_type i = 0; i < row_parallel_partitioning.size(); ++i)
652  for (size_type j = 0; j < col_parallel_partitioning.size(); ++j)
653  this->block(i, j).reinit(row_parallel_partitioning[i],
654  col_parallel_partitioning[j],
655  writable_rows[i],
656  communicator);
657  this->collect_sizes();
658  }
659 
660 } // namespace TrilinosWrappers
661 
662 #endif
663 
666 #ifdef DEAL_II_WITH_TRILINOS
668 #endif
669 
670 DEAL_II_NAMESPACE_CLOSE
static::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
bool exists(const size_type i, const size_type j) const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
void print(std::ostream &out) const
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
std::size_t memory_consumption() const
size_type size() const
Definition: index_set.h:1611
size_type n_nonzero_elements() const
SparsityPatternType & block(const size_type row, const size_type column)
void reinit(const size_type n_block_rows, const size_type n_block_columns)
void reinit(const size_type n_block_rows, const size_type n_block_columns)
static::ExceptionBase & ExcMessage(std::string arg1)
const IndexSet & row_index_set() const
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
Definition: exceptions.h:1227
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
BlockSparsityPatternBase & operator=(const BlockSparsityPatternBase &)
size_type max_entries_per_row() const
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
size_type block_size(const unsigned int i) const
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
Table< 2, SmartPointer< SparsityPatternType, BlockSparsityPatternBase< SparsityPatternType > > > sub_objects
void print_gnuplot(std::ostream &out) const
bool is_element(const size_type index) const
Definition: index_set.h:1676
unsigned int size() const
void copy_from(const BlockDynamicSparsityPattern &dsp)
types::global_dof_index size_type
size_type local_to_global(const unsigned int block, const size_type index) const
BlockSparsityPattern()=default
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static::ExceptionBase & ExcInternalError()