Reference documentation for deal.II version 8.5.1
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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/vector_slice.h>
18 #include <deal.II/base/memory_consumption.h>
19 #include <deal.II/lac/block_sparsity_pattern.h>
20 
21 DEAL_II_NAMESPACE_OPEN
22 
23 
24 template <class SparsityPatternBase>
26  :
27  rows (0),
28  columns (0)
29 {}
30 
31 
32 
33 template <class SparsityPatternBase>
35 BlockSparsityPatternBase (const size_type n_block_rows,
36  const size_type n_block_columns)
37  :
38  rows (0),
39  columns (0)
40 {
41  reinit (n_block_rows, n_block_columns);
42 }
43 
44 
45 
46 template <class SparsityPatternBase>
49  :
50  Subscriptor (),
51  rows (0),
52  columns (0)
53 {
54  (void)s;
55  Assert (s.rows==0 && s.columns==0,
56  ExcMessage("This constructor can only be called if the provided argument "
57  "is the sparsity pattern for an empty matrix. This constructor can "
58  "not be used to copy-construct a non-empty sparsity pattern."));
59 }
60 
61 
62 
63 template <class SparsityPatternBase>
65 {
66  // clear all memory
67  try
68  {
69  reinit (0,0);
70  }
71  catch (...)
72  {}
73 }
74 
75 
76 
77 template <class SparsityPatternBase>
78 void
80 reinit (const size_type n_block_rows,
81  const size_type n_block_columns)
82 {
83  // delete previous content and
84  // clean the sub_objects array
85  // completely
86  for (size_type i=0; i<rows; ++i)
87  for (size_type j=0; j<columns; ++j)
88  {
89  SparsityPatternBase *sp = sub_objects[i][j];
90  sub_objects[i][j] = 0;
91  delete sp;
92  };
93  sub_objects.reinit (0,0);
94 
95  // then set new sizes
96  rows = n_block_rows;
97  columns = n_block_columns;
98  sub_objects.reinit (rows, columns);
99 
100  // allocate new objects
101  for (size_type i=0; i<rows; ++i)
102  for (size_type j=0; j<columns; ++j)
103  {
104  SparsityPatternBase *p = new SparsityPatternBase;
105  sub_objects[i][j] = p;
106  }
107 }
108 
109 
110 template <class SparsityPatternBase>
114 {
115  Assert (rows == bsp.rows, ExcDimensionMismatch(rows, bsp.rows));
116  Assert (columns == bsp.columns, ExcDimensionMismatch(columns, bsp.columns));
117  // copy objects
118  for (size_type i=0; i<rows; ++i)
119  for (size_type j=0; j<columns; ++j)
120  *sub_objects[i][j] = *bsp.sub_objects[i][j];
121  // update index objects
122  collect_sizes ();
123 
124  return *this;
125 }
126 
127 
128 
129 template <class SparsityPatternBase>
130 void
132 {
133  std::vector<size_type > row_sizes (rows);
134  std::vector<size_type > col_sizes (columns);
135 
136  // first find out the row sizes
137  // from the first block column
138  for (size_type r=0; r<rows; ++r)
139  row_sizes[r] = sub_objects[r][0]->n_rows();
140  // then check that the following
141  // block columns have the same
142  // sizes
143  for (size_type c=1; c<columns; ++c)
144  for (size_type r=0; r<rows; ++r)
145  Assert (row_sizes[r] == sub_objects[r][c]->n_rows(),
146  ExcIncompatibleRowNumbers (r,0,r,c));
147 
148  // finally initialize the row
149  // indices with this array
150  row_indices.reinit (row_sizes);
151 
152 
153  // then do the same with the columns
154  for (size_type c=0; c<columns; ++c)
155  col_sizes[c] = sub_objects[0][c]->n_cols();
156  for (size_type r=1; r<rows; ++r)
157  for (size_type c=0; c<columns; ++c)
158  Assert (col_sizes[c] == sub_objects[r][c]->n_cols(),
159  ExcIncompatibleRowNumbers (0,c,r,c));
160 
161  // finally initialize the row
162  // indices with this array
163  column_indices.reinit (col_sizes);
164 }
165 
166 
167 
168 template <class SparsityPatternBase>
169 void
171 {
172  for (size_type i=0; i<rows; ++i)
173  for (size_type j=0; j<columns; ++j)
174  sub_objects[i][j]->compress ();
175 }
176 
177 
178 
179 template <class SparsityPatternBase>
180 bool
182 {
183  for (size_type i=0; i<rows; ++i)
184  for (size_type j=0; j<columns; ++j)
185  if (sub_objects[i][j]->empty () == false)
186  return false;
187  return true;
188 }
189 
190 
191 
192 template <class SparsityPatternBase>
195 {
196  size_type max_entries = 0;
197  for (size_type block_row=0; block_row<rows; ++block_row)
198  {
199  size_type this_row = 0;
200  for (size_type c=0; c<columns; ++c)
201  this_row += sub_objects[block_row][c]->max_entries_per_row ();
202 
203  if (this_row > max_entries)
204  max_entries = this_row;
205  };
206  return max_entries;
207 }
208 
209 
210 
211 template <class SparsityPatternBase>
214 {
215  // only count in first column, since
216  // all rows should be equivalent
217  size_type count = 0;
218  for (size_type r=0; r<rows; ++r)
219  count += sub_objects[r][0]->n_rows();
220  return count;
221 }
222 
223 
224 
225 template <class SparsityPatternBase>
228 {
229  // only count in first row, since
230  // all rows should be equivalent
231  size_type count = 0;
232  for (size_type c=0; c<columns; ++c)
233  count += sub_objects[0][c]->n_cols();
234  return count;
235 }
236 
237 
238 
239 template <class SparsityPatternBase>
242 {
243  size_type count = 0;
244  for (size_type i=0; i<rows; ++i)
245  for (size_type j=0; j<columns; ++j)
246  count += sub_objects[i][j]->n_nonzero_elements ();
247  return count;
248 }
249 
250 
251 
252 template <class SparsityPatternBase>
253 void
255 {
256  size_type k=0;
257  for (size_type ib=0; ib<n_block_rows(); ++ib)
258  {
259  for (size_type i=0; i<block(ib,0).n_rows(); ++i)
260  {
261  out << '[' << i+k;
262  size_type l=0;
263  for (size_type jb=0; jb<n_block_cols(); ++jb)
264  {
265  const SparsityPatternBase &b = block(ib,jb);
266  for (size_type j=0; j<b.n_cols(); ++j)
267  if (b.exists(i,j))
268  out << ',' << l+j;
269  l += b.n_cols();
270  }
271  out << ']' << std::endl;
272  }
273  k += block(ib,0).n_rows();
274  }
275 }
276 
277 
278 template <>
279 void
281 {
282  size_type k=0;
283  for (size_type ib=0; ib<n_block_rows(); ++ib)
284  {
285  for (size_type i=0; i<block(ib,0).n_rows(); ++i)
286  {
287  out << '[' << i+k;
288  size_type l=0;
289  for (size_type jb=0; jb<n_block_cols(); ++jb)
290  {
291  const DynamicSparsityPattern &b = block(ib,jb);
292  if (b.row_index_set().size()==0 || 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 {
309  size_type k=0;
310  for (size_type ib=0; ib<n_block_rows(); ++ib)
311  {
312  for (size_type i=0; i<block(ib,0).n_rows(); ++i)
313  {
314  size_type l=0;
315  for (size_type jb=0; jb<n_block_cols(); ++jb)
316  {
317  const SparsityPatternBase &b = block(ib,jb);
318  for (size_type j=0; j<b.n_cols(); ++j)
319  if (b.exists(i,j))
320  out << l+j << " " << -static_cast<signed int>(i+k) << std::endl;
321  l += b.n_cols();
322  }
323  }
324  k += block(ib,0).n_rows();
325  }
326 }
327 
328 
329 
331 {}
332 
333 
334 
336  const size_type n_columns)
337  :
339  n_columns)
340 {}
341 
342 
343 void
345  const BlockIndices &rows,
346  const BlockIndices &cols,
347  const std::vector<std::vector<unsigned int> > &row_lengths)
348 {
349  AssertDimension (row_lengths.size(), cols.size());
350 
351  this->reinit(rows.size(), cols.size());
352  for (size_type j=0; j<cols.size(); ++j)
353  for (size_type i=0; i<rows.size(); ++i)
354  {
355  const size_type start = rows.local_to_global(i, 0);
356  const size_type length = rows.block_size(i);
357 
358  if (row_lengths[j].size()==1)
359  block(i,j).reinit(rows.block_size(i),
360  cols.block_size(j), row_lengths[j][0]);
361  else
362  {
364  block_rows(row_lengths[j], start, length);
365  block(i,j).reinit(rows.block_size(i),
366  cols.block_size(j),
367  block_rows);
368  }
369  }
370  this->collect_sizes();
371  Assert (this->row_indices == rows, ExcInternalError());
372  Assert (this->column_indices == cols, ExcInternalError());
373 }
374 
375 
376 bool
378 {
379  for (size_type i=0; i<rows; ++i)
380  for (size_type j=0; j<columns; ++j)
381  if (sub_objects[i][j]->is_compressed () == false)
382  return false;
383  return true;
384 }
385 
386 
387 std::size_t
389 {
390  std::size_t mem = 0;
396  for (size_type r=0; r<rows; ++r)
397  for (size_type c=0; c<columns; ++c)
399 
400  return mem;
401 }
402 
403 
404 
405 void
407 {
408  // delete old content, set block
409  // sizes anew
410  reinit (dsp.n_block_rows(), dsp.n_block_cols());
411 
412  // copy over blocks
413  for (size_type i=0; i<n_block_rows(); ++i)
414  for (size_type j=0; j<n_block_cols(); ++j)
415  block(i,j).copy_from (dsp.block(i,j));
416 
417  // and finally enquire their new
418  // sizes
419  collect_sizes();
420 }
421 
422 
423 
424 
426 {}
427 
428 
429 
431 BlockDynamicSparsityPattern (const size_type n_rows,
432  const size_type n_columns)
433  :
435  n_columns)
436 {}
437 
438 
439 
441 BlockDynamicSparsityPattern (const std::vector<size_type> &row_indices,
442  const std::vector<size_type> &col_indices)
443  :
445  col_indices.size())
446 {
447  for (size_type i=0; i<row_indices.size(); ++i)
448  for (size_type j=0; j<col_indices.size(); ++j)
449  this->block(i,j).reinit(row_indices[i],col_indices[j]);
450  this->collect_sizes();
451 }
452 
453 
455 BlockDynamicSparsityPattern (const std::vector<IndexSet> &partitioning)
456  :
458  partitioning.size())
459 {
460  for (size_type i=0; i<partitioning.size(); ++i)
461  for (size_type j=0; j<partitioning.size(); ++j)
462  this->block(i,j).reinit(partitioning[i].size(),
463  partitioning[j].size(),
464  partitioning[i]);
465  this->collect_sizes();
466 }
467 
468 
471  const BlockIndices &col_indices)
472 {
473  reinit(row_indices, col_indices);
474 }
475 
476 
477 void
479  const std::vector<size_type> &row_block_sizes,
480  const std::vector<size_type> &col_block_sizes)
481 {
483  reinit(row_block_sizes.size(), col_block_sizes.size());
484  for (size_type i=0; i<row_block_sizes.size(); ++i)
485  for (size_type j=0; j<col_block_sizes.size(); ++j)
486  this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
487  this->collect_sizes();
488 }
489 
490 void
492  const std::vector< IndexSet > &partitioning)
493 {
495  reinit(partitioning.size(), partitioning.size());
496  for (size_type i=0; i<partitioning.size(); ++i)
497  for (size_type j=0; j<partitioning.size(); ++j)
498  this->block(i,j).reinit(partitioning[i].size(),
499  partitioning[j].size(),
500  partitioning[i]);
501  this->collect_sizes();
502 }
503 
504 void
506  const BlockIndices &row_indices,
507  const BlockIndices &col_indices)
508 {
510  col_indices.size());
511  for (size_type i=0; i<row_indices.size(); ++i)
512  for (size_type j=0; j<col_indices.size(); ++j)
513  this->block(i,j).reinit(row_indices.block_size(i),
514  col_indices.block_size(j));
515  this->collect_sizes();
516 }
517 
518 
519 #ifdef DEAL_II_WITH_TRILINOS
520 namespace TrilinosWrappers
521 {
522 
524  {}
525 
526 
527 
529  BlockSparsityPattern (const size_type n_rows,
530  const size_type n_columns)
531  :
533  n_columns)
534  {}
535 
536 
537 
539  BlockSparsityPattern (const std::vector<size_type> &row_indices,
540  const std::vector<size_type> &col_indices)
541  :
542  BlockSparsityPatternBase<SparsityPattern>(row_indices.size(),
543  col_indices.size())
544  {
545  for (size_type i=0; i<row_indices.size(); ++i)
546  for (size_type j=0; j<col_indices.size(); ++j)
547  this->block(i,j).reinit(row_indices[i],col_indices[j]);
548  this->collect_sizes();
549  }
550 
551 
552 
554  BlockSparsityPattern (const std::vector<Epetra_Map> &parallel_partitioning)
555  :
557  (parallel_partitioning.size(),
558  parallel_partitioning.size())
559  {
560  for (size_type i=0; i<parallel_partitioning.size(); ++i)
561  for (size_type j=0; j<parallel_partitioning.size(); ++j)
562  this->block(i,j).reinit(parallel_partitioning[i],
563  parallel_partitioning[j]);
564  this->collect_sizes();
565  }
566 
567 
568 
570  BlockSparsityPattern (const std::vector<IndexSet> &parallel_partitioning,
571  const MPI_Comm &communicator)
572  :
574  (parallel_partitioning.size(),
575  parallel_partitioning.size())
576  {
577  for (size_type i=0; i<parallel_partitioning.size(); ++i)
578  for (size_type j=0; j<parallel_partitioning.size(); ++j)
579  this->block(i,j).reinit(parallel_partitioning[i],
580  parallel_partitioning[j],
581  communicator);
582  this->collect_sizes();
583  }
584 
585 
586 
588  BlockSparsityPattern (const std::vector<IndexSet> &row_parallel_partitioning,
589  const std::vector<IndexSet> &col_parallel_partitioning,
590  const std::vector<IndexSet> &writable_rows,
591  const MPI_Comm &communicator)
592  :
594  (row_parallel_partitioning.size(),
595  col_parallel_partitioning.size())
596  {
597  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
598  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
599  this->block(i,j).reinit(row_parallel_partitioning[i],
600  col_parallel_partitioning[j],
601  writable_rows[i],
602  communicator);
603  this->collect_sizes();
604  }
605 
606 
607 
608  void
609  BlockSparsityPattern::reinit (const std::vector<size_type> &row_block_sizes,
610  const std::vector<size_type> &col_block_sizes)
611  {
613  reinit(row_block_sizes.size(), col_block_sizes.size());
614  for (size_type i=0; i<row_block_sizes.size(); ++i)
615  for (size_type j=0; j<col_block_sizes.size(); ++j)
616  this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
617  this->collect_sizes();
618  }
619 
620 
621 
622  void
623  BlockSparsityPattern::reinit (const std::vector<Epetra_Map> &parallel_partitioning)
624  {
626  reinit(parallel_partitioning.size(),
627  parallel_partitioning.size());
628  for (size_type i=0; i<parallel_partitioning.size(); ++i)
629  for (size_type j=0; j<parallel_partitioning.size(); ++j)
630  this->block(i,j).reinit(parallel_partitioning[i],
631  parallel_partitioning[j]);
632  this->collect_sizes();
633  }
634 
635 
636 
637  void
638  BlockSparsityPattern::reinit (const std::vector<IndexSet> &parallel_partitioning,
639  const MPI_Comm &communicator)
640  {
642  reinit(parallel_partitioning.size(),
643  parallel_partitioning.size());
644  for (size_type i=0; i<parallel_partitioning.size(); ++i)
645  for (size_type j=0; j<parallel_partitioning.size(); ++j)
646  this->block(i,j).reinit(parallel_partitioning[i],
647  parallel_partitioning[j],
648  communicator);
649  this->collect_sizes();
650  }
651 
652 
653 
654  void
655  BlockSparsityPattern::reinit (const std::vector<IndexSet> &row_parallel_partitioning,
656  const std::vector<IndexSet> &col_parallel_partitioning,
657  const MPI_Comm &communicator)
658  {
660  reinit(row_parallel_partitioning.size(),
661  col_parallel_partitioning.size());
662  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
663  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
664  this->block(i,j).reinit(row_parallel_partitioning[i],
665  col_parallel_partitioning[j],
666  communicator);
667  this->collect_sizes();
668  }
669 
670 
671 
672  void
673  BlockSparsityPattern::reinit (const std::vector<IndexSet> &row_parallel_partitioning,
674  const std::vector<IndexSet> &col_parallel_partitioning,
675  const std::vector<IndexSet> &writable_rows,
676  const MPI_Comm &communicator)
677  {
678  AssertDimension(writable_rows.size(), row_parallel_partitioning.size());
680  reinit(row_parallel_partitioning.size(),
681  col_parallel_partitioning.size());
682  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
683  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
684  this->block(i,j).reinit(row_parallel_partitioning[i],
685  col_parallel_partitioning[j],
686  writable_rows[i],
687  communicator);
688  this->collect_sizes();
689  }
690 
691 }
692 
693 #endif
694 
697 #ifdef DEAL_II_WITH_TRILINOS
699 #endif
700 
701 DEAL_II_NAMESPACE_CLOSE
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
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
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)
std::size_t memory_consumption() const
void print(std::ostream &out) const
#define Assert(cond, exc)
Definition: exceptions.h:313
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)
BlockSparsityPatternBase & operator=(const BlockSparsityPatternBase &)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
Table< 2, SmartPointer< SparsityPatternType, BlockSparsityPatternBase< SparsityPatternType > > > sub_objects
void print_gnuplot(std::ostream &out) const
void copy_from(const BlockDynamicSparsityPattern &dsp)
unsigned int size() const
static ::ExceptionBase & ExcInternalError()