Reference documentation for deal.II version 9.0.0
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] = nullptr;
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  const size_type n_columns)
332  :
334  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), row_lengths[j][0]);
356  else
357  {
359  block_rows(row_lengths[j], start, length);
360  block(i,j).reinit(rows.block_size(i),
361  cols.block_size(j),
362  block_rows);
363  }
364  }
365  this->collect_sizes();
366  Assert (this->row_indices == rows, ExcInternalError());
367  Assert (this->column_indices == cols, ExcInternalError());
368 }
369 
370 
371 bool
373 {
374  for (size_type i=0; i<rows; ++i)
375  for (size_type j=0; j<columns; ++j)
376  if (sub_objects[i][j]->is_compressed () == false)
377  return false;
378  return true;
379 }
380 
381 
382 std::size_t
384 {
385  std::size_t mem = 0;
391  for (size_type r=0; r<rows; ++r)
392  for (size_type c=0; c<columns; ++c)
394 
395  return mem;
396 }
397 
398 
399 
400 void
402 {
403  // delete old content, set block
404  // sizes anew
405  reinit (dsp.n_block_rows(), dsp.n_block_cols());
406 
407  // copy over blocks
408  for (size_type i=0; i<n_block_rows(); ++i)
409  for (size_type j=0; j<n_block_cols(); ++j)
410  block(i,j).copy_from (dsp.block(i,j));
411 
412  // and finally enquire their new
413  // sizes
414  collect_sizes();
415 }
416 
417 
418 
420 BlockDynamicSparsityPattern (const size_type n_rows,
421  const size_type n_columns)
422  :
424  n_columns)
425 {}
426 
427 
428 
430 BlockDynamicSparsityPattern (const std::vector<size_type> &row_indices,
431  const std::vector<size_type> &col_indices)
432  :
434  col_indices.size())
435 {
436  for (size_type i=0; i<row_indices.size(); ++i)
437  for (size_type j=0; j<col_indices.size(); ++j)
438  this->block(i,j).reinit(row_indices[i],col_indices[j]);
439  this->collect_sizes();
440 }
441 
442 
444 BlockDynamicSparsityPattern (const std::vector<IndexSet> &partitioning)
445  :
447  partitioning.size())
448 {
449  for (size_type i=0; i<partitioning.size(); ++i)
450  for (size_type j=0; j<partitioning.size(); ++j)
451  this->block(i,j).reinit(partitioning[i].size(),
452  partitioning[j].size(),
453  partitioning[i]);
454  this->collect_sizes();
455 }
456 
457 
460  const BlockIndices &col_indices)
461 {
462  reinit(row_indices, col_indices);
463 }
464 
465 
466 void
468  const std::vector<size_type> &row_block_sizes,
469  const std::vector<size_type> &col_block_sizes)
470 {
472  reinit(row_block_sizes.size(), col_block_sizes.size());
473  for (size_type i=0; i<row_block_sizes.size(); ++i)
474  for (size_type j=0; j<col_block_sizes.size(); ++j)
475  this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
476  this->collect_sizes();
477 }
478 
479 void
481  const std::vector< IndexSet > &partitioning)
482 {
484  reinit(partitioning.size(), partitioning.size());
485  for (size_type i=0; i<partitioning.size(); ++i)
486  for (size_type j=0; j<partitioning.size(); ++j)
487  this->block(i,j).reinit(partitioning[i].size(),
488  partitioning[j].size(),
489  partitioning[i]);
490  this->collect_sizes();
491 }
492 
493 void
495  const BlockIndices &row_indices,
496  const BlockIndices &col_indices)
497 {
499  col_indices.size());
500  for (size_type i=0; i<row_indices.size(); ++i)
501  for (size_type j=0; j<col_indices.size(); ++j)
502  this->block(i,j).reinit(row_indices.block_size(i),
503  col_indices.block_size(j));
504  this->collect_sizes();
505 }
506 
507 
508 #ifdef DEAL_II_WITH_TRILINOS
509 namespace TrilinosWrappers
510 {
511 
513  BlockSparsityPattern (const size_type n_rows,
514  const size_type n_columns)
515  :
517  n_columns)
518  {}
519 
520 
521 
523  BlockSparsityPattern (const std::vector<size_type> &row_indices,
524  const std::vector<size_type> &col_indices)
525  :
526  BlockSparsityPatternBase<SparsityPattern>(row_indices.size(),
527  col_indices.size())
528  {
529  for (size_type i=0; i<row_indices.size(); ++i)
530  for (size_type j=0; j<col_indices.size(); ++j)
531  this->block(i,j).reinit(row_indices[i],col_indices[j]);
532  this->collect_sizes();
533  }
534 
535 
536 
538  BlockSparsityPattern (const std::vector<Epetra_Map> &parallel_partitioning)
539  :
541  (parallel_partitioning.size(),
542  parallel_partitioning.size())
543  {
544  for (size_type i=0; i<parallel_partitioning.size(); ++i)
545  for (size_type j=0; j<parallel_partitioning.size(); ++j)
546  this->block(i,j).reinit(parallel_partitioning[i],
547  parallel_partitioning[j]);
548  this->collect_sizes();
549  }
550 
551 
552 
554  BlockSparsityPattern (const std::vector<IndexSet> &parallel_partitioning,
555  const MPI_Comm &communicator)
556  :
558  (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  BlockSparsityPattern (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)
576  :
578  (row_parallel_partitioning.size(),
579  col_parallel_partitioning.size())
580  {
581  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
582  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
583  this->block(i,j).reinit(row_parallel_partitioning[i],
584  col_parallel_partitioning[j],
585  writable_rows[i],
586  communicator);
587  this->collect_sizes();
588  }
589 
590 
591 
592  void
593  BlockSparsityPattern::reinit (const std::vector<size_type> &row_block_sizes,
594  const std::vector<size_type> &col_block_sizes)
595  {
597  reinit(row_block_sizes.size(), col_block_sizes.size());
598  for (size_type i=0; i<row_block_sizes.size(); ++i)
599  for (size_type j=0; j<col_block_sizes.size(); ++j)
600  this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
601  this->collect_sizes();
602  }
603 
604 
605 
606  void
607  BlockSparsityPattern::reinit (const std::vector<Epetra_Map> &parallel_partitioning)
608  {
610  reinit(parallel_partitioning.size(),
611  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  this->collect_sizes();
617  }
618 
619 
620 
621  void
622  BlockSparsityPattern::reinit (const std::vector<IndexSet> &parallel_partitioning,
623  const MPI_Comm &communicator)
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  communicator);
633  this->collect_sizes();
634  }
635 
636 
637 
638  void
639  BlockSparsityPattern::reinit (const std::vector<IndexSet> &row_parallel_partitioning,
640  const std::vector<IndexSet> &col_parallel_partitioning,
641  const MPI_Comm &communicator)
642  {
644  reinit(row_parallel_partitioning.size(),
645  col_parallel_partitioning.size());
646  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
647  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
648  this->block(i,j).reinit(row_parallel_partitioning[i],
649  col_parallel_partitioning[j],
650  communicator);
651  this->collect_sizes();
652  }
653 
654 
655 
656  void
657  BlockSparsityPattern::reinit (const std::vector<IndexSet> &row_parallel_partitioning,
658  const std::vector<IndexSet> &col_parallel_partitioning,
659  const std::vector<IndexSet> &writable_rows,
660  const MPI_Comm &communicator)
661  {
662  AssertDimension(writable_rows.size(), row_parallel_partitioning.size());
664  reinit(row_parallel_partitioning.size(),
665  col_parallel_partitioning.size());
666  for (size_type i=0; i<row_parallel_partitioning.size(); ++i)
667  for (size_type j=0; j<col_parallel_partitioning.size(); ++j)
668  this->block(i,j).reinit(row_parallel_partitioning[i],
669  col_parallel_partitioning[j],
670  writable_rows[i],
671  communicator);
672  this->collect_sizes();
673  }
674 
675 }
676 
677 #endif
678 
681 #ifdef DEAL_II_WITH_TRILINOS
683 #endif
684 
685 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:1248
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:1142
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)
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
BlockSparsityPattern()=default
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()