Reference documentation for deal.II version 9.0.0
petsc_parallel_sparse_matrix.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2018 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 #include <deal.II/lac/petsc_parallel_sparse_matrix.h>
17 
18 #ifdef DEAL_II_WITH_PETSC
19 
20 # include <deal.II/base/mpi.h>
21 # include <deal.II/lac/exceptions.h>
22 # include <deal.II/lac/petsc_compatibility.h>
23 # include <deal.II/lac/petsc_parallel_vector.h>
24 # include <deal.II/lac/sparsity_pattern.h>
25 # include <deal.II/lac/dynamic_sparsity_pattern.h>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 namespace PETScWrappers
30 {
31  namespace MPI
32  {
34  : communicator(MPI_COMM_SELF)
35  {
36  // just like for vectors: since we
37  // create an empty matrix, we can as
38  // well make it sequential
39  const int m=0, n=0, n_nonzero_per_row=0;
40  const PetscErrorCode ierr
41  = MatCreateSeqAIJ(PETSC_COMM_SELF, m, n, n_nonzero_per_row,
42  nullptr, &matrix);
43  AssertThrow (ierr == 0, ExcPETScError(ierr));
44  }
45 
46 
48  {
50  }
51 
52  SparseMatrix::SparseMatrix (const MPI_Comm &communicator,
53  const size_type m,
54  const size_type n,
55  const size_type local_rows,
56  const size_type local_columns,
57  const size_type n_nonzero_per_row,
58  const bool is_symmetric,
59  const size_type n_offdiag_nonzero_per_row)
60  :
61  communicator (communicator)
62  {
63  do_reinit (m, n, local_rows, local_columns,
64  n_nonzero_per_row, is_symmetric,
65  n_offdiag_nonzero_per_row);
66  }
67 
68 
69 
70  SparseMatrix::SparseMatrix (const MPI_Comm &communicator,
71  const size_type m,
72  const size_type n,
73  const size_type local_rows,
74  const size_type local_columns,
75  const std::vector<size_type> &row_lengths,
76  const bool is_symmetric,
77  const std::vector<size_type> &offdiag_row_lengths)
78  :
79  communicator (communicator)
80  {
81  do_reinit (m, n, local_rows, local_columns,
82  row_lengths, is_symmetric, offdiag_row_lengths);
83  }
84 
85 
86 
87  template <typename SparsityPatternType>
89  SparseMatrix (const MPI_Comm &communicator,
90  const SparsityPatternType &sparsity_pattern,
91  const std::vector<size_type> &local_rows_per_process,
92  const std::vector<size_type> &local_columns_per_process,
93  const unsigned int this_process,
94  const bool preset_nonzero_locations)
95  :
96  communicator (communicator)
97  {
98  do_reinit (sparsity_pattern, local_rows_per_process,
99  local_columns_per_process, this_process,
100  preset_nonzero_locations);
101  }
102 
103 
104  void
106  reinit (const SparseMatrix &other)
107  {
108  if (&other == this)
109  return;
110 
111  this->communicator = other.communicator;
112 
113  PetscErrorCode ierr = destroy_matrix (matrix);
114  AssertThrow (ierr == 0, ExcPETScError(ierr));
115 
116  ierr = MatDuplicate (other.matrix, MAT_DO_NOT_COPY_VALUES, &matrix);
117  AssertThrow (ierr == 0, ExcPETScError(ierr));
118  }
119 
120 
121  SparseMatrix &
123  {
125  return *this;
126  }
127 
128  void
130  {
131  if (&other == this)
132  return;
133 
134  this->communicator = other.communicator;
135 
136  const PetscErrorCode ierr = MatCopy(other.matrix, matrix,
137  SAME_NONZERO_PATTERN);
138  AssertThrow (ierr == 0, ExcPETScError(ierr));
139  }
140 
141  void
142  SparseMatrix::reinit (const MPI_Comm &communicator,
143  const size_type m,
144  const size_type n,
145  const size_type local_rows,
146  const size_type local_columns,
147  const size_type n_nonzero_per_row,
148  const bool is_symmetric,
149  const size_type n_offdiag_nonzero_per_row)
150  {
151  this->communicator = communicator;
152 
153  // get rid of old matrix and generate a new one
154  const PetscErrorCode ierr = destroy_matrix (matrix);
155  AssertThrow (ierr == 0, ExcPETScError (ierr));
156 
157  do_reinit (m, n, local_rows, local_columns,
158  n_nonzero_per_row, is_symmetric,
159  n_offdiag_nonzero_per_row);
160  }
161 
162 
163 
164  void
165  SparseMatrix::reinit (const MPI_Comm &communicator,
166  const size_type m,
167  const size_type n,
168  const size_type local_rows,
169  const size_type local_columns,
170  const std::vector<size_type> &row_lengths,
171  const bool is_symmetric,
172  const std::vector<size_type> &offdiag_row_lengths)
173  {
174  this->communicator = communicator;
175 
176  // get rid of old matrix and generate a
177  // new one
178  const PetscErrorCode ierr = destroy_matrix (matrix);
179  AssertThrow (ierr == 0, ExcPETScError (ierr));
180 
181  do_reinit (m, n, local_rows, local_columns,
182  row_lengths, is_symmetric, offdiag_row_lengths);
183  }
184 
185 
186 
187  template <typename SparsityPatternType>
188  void
190  reinit (const MPI_Comm &communicator,
191  const SparsityPatternType &sparsity_pattern,
192  const std::vector<size_type> &local_rows_per_process,
193  const std::vector<size_type> &local_columns_per_process,
194  const unsigned int this_process,
195  const bool preset_nonzero_locations)
196  {
197  this->communicator = communicator;
198 
199  // get rid of old matrix and generate a new one
200  const PetscErrorCode ierr = destroy_matrix (matrix);
201  AssertThrow (ierr == 0, ExcPETScError (ierr));
202 
203 
204  do_reinit (sparsity_pattern, local_rows_per_process,
205  local_columns_per_process, this_process,
206  preset_nonzero_locations);
207  }
208 
209  template <typename SparsityPatternType>
210  void
212  reinit (const IndexSet &local_rows,
213  const IndexSet &local_columns,
214  const SparsityPatternType &sparsity_pattern,
215  const MPI_Comm &communicator)
216  {
217  this->communicator = communicator;
218 
219  // get rid of old matrix and generate a new one
220  const PetscErrorCode ierr = destroy_matrix (matrix);
221  AssertThrow(ierr == 0, ExcPETScError (ierr));
222 
223  do_reinit (local_rows, local_columns, sparsity_pattern);
224  }
225 
226  void
228  const size_type n,
229  const size_type local_rows,
230  const size_type local_columns,
231  const size_type n_nonzero_per_row,
232  const bool is_symmetric,
233  const size_type n_offdiag_nonzero_per_row)
234  {
235  Assert (local_rows <= m, ExcLocalRowsTooLarge (local_rows, m));
236 
237  // use the call sequence indicating only
238  // a maximal number of elements per row
239  // for all rows globally
240  const PetscErrorCode ierr = MatCreateAIJ
241  (communicator,
242  local_rows, local_columns,
243  m, n,
244  n_nonzero_per_row, nullptr,
245  n_offdiag_nonzero_per_row, nullptr,
246  &matrix);
247  set_matrix_option (matrix, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
248  AssertThrow (ierr == 0, ExcPETScError(ierr));
249 
250  // set symmetric flag, if so requested
251  if (is_symmetric == true)
252  {
253  set_matrix_option (matrix, MAT_SYMMETRIC, PETSC_TRUE);
254  }
255  }
256 
257 
258 
259  void
261  const size_type n,
262  const size_type local_rows,
263  const size_type local_columns,
264  const std::vector<size_type> &row_lengths,
265  const bool is_symmetric,
266  const std::vector<size_type> &offdiag_row_lengths)
267  {
268  Assert (local_rows <= m, ExcLocalRowsTooLarge (local_rows, m));
269 
270  Assert (row_lengths.size() == m,
271  ExcDimensionMismatch (row_lengths.size(), m));
272 
273  // For the case that
274  // local_columns is smaller
275  // than one of the row lengths
276  // MatCreateMPIAIJ throws an
277  // error. In this case use a
278  // PETScWrappers::SparseMatrix
279  for (size_type i=0; i<row_lengths.size(); ++i)
280  Assert(row_lengths[i]<=local_columns,
281  ExcIndexRange(row_lengths[i], 1, local_columns+1));
282 
283  // use the call sequence indicating a
284  // maximal number of elements for each
285  // row individually. annoyingly, we
286  // always use unsigned ints for cases
287  // like this, while PETSc wants to see
288  // signed integers. so we have to
289  // convert, unless we want to play dirty
290  // tricks with conversions of pointers
291  const std::vector<PetscInt> int_row_lengths (row_lengths.begin(),
292  row_lengths.end());
293  const std::vector<PetscInt> int_offdiag_row_lengths (offdiag_row_lengths.begin(),
294  offdiag_row_lengths.end());
295 
296 //TODO: There must be a significantly better way to provide information about the off-diagonal blocks of the matrix. this way, petsc keeps allocating tiny chunks of memory, and gets completely hung up over this
297  const PetscErrorCode ierr = MatCreateAIJ
298  (communicator,
299  local_rows, local_columns,
300  m, n,
301  0, int_row_lengths.data(),
302  0,
303  offdiag_row_lengths.size() ? int_offdiag_row_lengths.data() : nullptr,
304  &matrix);
305 
306 //TODO: Sometimes the actual number of nonzero entries allocated is greater than the number of nonzero entries, which petsc will complain about unless explicitly disabled with MatSetOption. There is probably a way to prevent a different number nonzero elements being allocated in the first place. (See also previous TODO).
307  set_matrix_option (matrix, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
308  AssertThrow (ierr == 0, ExcPETScError(ierr));
309 
310  // set symmetric flag, if so requested
311  if (is_symmetric == true)
312  {
313  set_matrix_option (matrix, MAT_SYMMETRIC, PETSC_TRUE);
314  }
315  }
316 
317 
318  template <typename SparsityPatternType>
319  void
321  do_reinit (const IndexSet &local_rows,
322  const IndexSet &local_columns,
323  const SparsityPatternType &sparsity_pattern)
324  {
325  Assert(sparsity_pattern.n_rows()==local_rows.size(),
326  ExcMessage("SparsityPattern and IndexSet have different number of rows"));
327  Assert(sparsity_pattern.n_cols()==local_columns.size(),
328  ExcMessage("SparsityPattern and IndexSet have different number of columns"));
329  Assert(local_rows.is_contiguous() && local_columns.is_contiguous(),
330  ExcMessage("PETSc only supports contiguous row/column ranges"));
332 
333 #ifdef DEBUG
334  {
335  // check indexsets
338  Assert(row_owners == sparsity_pattern.n_rows(),
339  ExcMessage(std::string("Each row has to be owned by exactly one owner (n_rows()=")
340  + Utilities::to_string(sparsity_pattern.n_rows())
341  + " but sum(local_rows.n_elements())="
342  + Utilities::to_string(row_owners)
343  + ")"));
344  Assert(col_owners == sparsity_pattern.n_cols(),
345  ExcMessage(std::string("Each column has to be owned by exactly one owner (n_cols()=")
346  + Utilities::to_string(sparsity_pattern.n_cols())
347  + " but sum(local_columns.n_elements())="
348  + Utilities::to_string(col_owners)
349  + ")"));
350  }
351 #endif
352 
353 
354  // create the matrix. We do not set row length but set the
355  // correct SparsityPattern later.
356  PetscErrorCode ierr = MatCreate(communicator,&matrix);
357  AssertThrow (ierr == 0, ExcPETScError(ierr));
358 
359  ierr = MatSetSizes(matrix,
360  local_rows.n_elements(),
361  local_columns.n_elements(),
362  sparsity_pattern.n_rows(),
363  sparsity_pattern.n_cols());
364  AssertThrow (ierr == 0, ExcPETScError(ierr));
365 
366  ierr = MatSetType(matrix,MATMPIAIJ);
367  AssertThrow (ierr == 0, ExcPETScError(ierr));
368 
369 
370  // next preset the exact given matrix
371  // entries with zeros. this doesn't avoid any
372  // memory allocations, but it at least
373  // avoids some searches later on. the
374  // key here is that we can use the
375  // matrix set routines that set an
376  // entire row at once, not a single
377  // entry at a time
378  //
379  // for the usefulness of this option
380  // read the documentation of this
381  // class.
382  //if (preset_nonzero_locations == true)
383  if (local_rows.n_elements()>0)
384  {
385  Assert(local_columns.n_elements()>0, ExcInternalError());
386  // MatMPIAIJSetPreallocationCSR
387  // can be used to allocate the sparsity
388  // pattern of a matrix
389 
390  const PetscInt local_row_start = local_rows.nth_index_in_set(0);
391  const PetscInt
392  local_row_end = local_row_start + local_rows.n_elements();
393 
394 
395  // first set up the column number
396  // array for the rows to be stored
397  // on the local processor. have one
398  // dummy entry at the end to make
399  // sure petsc doesn't read past the
400  // end
401  std::vector<PetscInt>
402 
403  rowstart_in_window (local_row_end - local_row_start + 1, 0),
404  colnums_in_window;
405  {
406  unsigned int n_cols = 0;
407  for (PetscInt i=local_row_start; i<local_row_end; ++i)
408  {
409  const PetscInt row_length = sparsity_pattern.row_length(i);
410  rowstart_in_window[i+1-local_row_start]
411  = rowstart_in_window[i-local_row_start] + row_length;
412  n_cols += row_length;
413  }
414  colnums_in_window.resize (n_cols+1, -1);
415  }
416 
417  // now copy over the information
418  // from the sparsity pattern.
419  {
420  PetscInt *ptr = & colnums_in_window[0];
421  for (PetscInt i=local_row_start; i<local_row_end; ++i)
422  for (typename SparsityPatternType::iterator p=sparsity_pattern.begin(i);
423  p != sparsity_pattern.end(i); ++p, ++ptr)
424  *ptr = p->column();
425  }
426 
427 
428  // then call the petsc function
429  // that summarily allocates these
430  // entries:
431  ierr = MatMPIAIJSetPreallocationCSR (matrix,
432  rowstart_in_window.data(),
433  colnums_in_window.data(),
434  nullptr);
435  AssertThrow (ierr == 0, ExcPETScError(ierr));
436  }
437  else
438  {
439  PetscInt i=0;
440  ierr = MatMPIAIJSetPreallocationCSR (matrix,
441  &i,
442  &i,
443  nullptr);
444  AssertThrow (ierr == 0, ExcPETScError(ierr));
445  }
447 
448  {
451  }
452  }
453 
454 
455  template <typename SparsityPatternType>
456  void
458  do_reinit (const SparsityPatternType &sparsity_pattern,
459  const std::vector<size_type> &local_rows_per_process,
460  const std::vector<size_type> &local_columns_per_process,
461  const unsigned int this_process,
462  const bool preset_nonzero_locations)
463  {
464  Assert (local_rows_per_process.size() == local_columns_per_process.size(),
465  ExcDimensionMismatch (local_rows_per_process.size(),
466  local_columns_per_process.size()));
467  Assert (this_process < local_rows_per_process.size(),
468  ExcInternalError());
470 
471  // for each row that we own locally, we
472  // have to count how many of the
473  // entries in the sparsity pattern lie
474  // in the column area we have locally,
475  // and how many aren't. for this, we
476  // first have to know which areas are
477  // ours
478  size_type local_row_start = 0;
479  size_type local_col_start = 0;
480  for (unsigned int p=0; p<this_process; ++p)
481  {
482  local_row_start += local_rows_per_process[p];
483  local_col_start += local_columns_per_process[p];
484  }
485  const size_type
486  local_row_end = local_row_start + local_rows_per_process[this_process];
487 
488  // create the matrix. We
489  // do not set row length but set the
490  // correct SparsityPattern later.
491  PetscErrorCode ierr = MatCreate(communicator,&matrix);
492  AssertThrow (ierr == 0, ExcPETScError(ierr));
493 
494  ierr = MatSetSizes(matrix,
495  local_rows_per_process[this_process],
496  local_columns_per_process[this_process],
497  sparsity_pattern.n_rows(),
498  sparsity_pattern.n_cols());
499  AssertThrow (ierr == 0, ExcPETScError(ierr));
500 
501  ierr = MatSetType(matrix,MATMPIAIJ);
502  AssertThrow (ierr == 0, ExcPETScError(ierr));
503 
504  // next preset the exact given matrix
505  // entries with zeros, if the user
506  // requested so. this doesn't avoid any
507  // memory allocations, but it at least
508  // avoids some searches later on. the
509  // key here is that we can use the
510  // matrix set routines that set an
511  // entire row at once, not a single
512  // entry at a time
513  //
514  // for the usefulness of this option
515  // read the documentation of this
516  // class.
517  if (preset_nonzero_locations == true)
518  {
519  // MatMPIAIJSetPreallocationCSR
520  // can be used to allocate the sparsity
521  // pattern of a matrix if it is already
522  // available:
523 
524  // first set up the column number
525  // array for the rows to be stored
526  // on the local processor. have one
527  // dummy entry at the end to make
528  // sure petsc doesn't read past the
529  // end
530  std::vector<PetscInt>
531 
532  rowstart_in_window (local_row_end - local_row_start + 1, 0),
533  colnums_in_window;
534  {
535  size_type n_cols = 0;
536  for (size_type i=local_row_start; i<local_row_end; ++i)
537  {
538  const size_type row_length = sparsity_pattern.row_length(i);
539  rowstart_in_window[i+1-local_row_start]
540  = rowstart_in_window[i-local_row_start] + row_length;
541  n_cols += row_length;
542  }
543  colnums_in_window.resize (n_cols+1, -1);
544  }
545 
546  // now copy over the information
547  // from the sparsity pattern.
548  {
549  PetscInt *ptr = & colnums_in_window[0];
550  for (size_type i=local_row_start; i<local_row_end; ++i)
551  for (typename SparsityPatternType::iterator p=sparsity_pattern.begin(i);
552  p != sparsity_pattern.end(i); ++p, ++ptr)
553  *ptr = p->column();
554  }
555 
556 
557  // then call the petsc function
558  // that summarily allocates these
559  // entries:
560  ierr = MatMPIAIJSetPreallocationCSR (matrix,
561  rowstart_in_window.data(),
562  colnums_in_window.data(),
563  nullptr);
564  AssertThrow (ierr == 0, ExcPETScError(ierr));
565 
568  }
569  }
570 
571  // explicit instantiations
572  //
573  template
574  SparseMatrix::SparseMatrix (const MPI_Comm &,
575  const SparsityPattern &,
576  const std::vector<size_type> &,
577  const std::vector<size_type> &,
578  const unsigned int,
579  const bool);
580  template
581  SparseMatrix::SparseMatrix (const MPI_Comm &,
582  const DynamicSparsityPattern &,
583  const std::vector<size_type> &,
584  const std::vector<size_type> &,
585  const unsigned int,
586  const bool);
587 
588  template void
589  SparseMatrix::reinit (const MPI_Comm &,
590  const SparsityPattern &,
591  const std::vector<size_type> &,
592  const std::vector<size_type> &,
593  const unsigned int,
594  const bool);
595  template void
596  SparseMatrix::reinit (const MPI_Comm &,
597  const DynamicSparsityPattern &,
598  const std::vector<size_type> &,
599  const std::vector<size_type> &,
600  const unsigned int,
601  const bool);
602 
603  template void
605  reinit (const IndexSet &,
606  const IndexSet &,
607  const SparsityPattern &,
608  const MPI_Comm &);
609 
610  template void
612  reinit (const IndexSet &,
613  const IndexSet &,
614  const DynamicSparsityPattern &,
615  const MPI_Comm &);
616 
617  template void
619  const std::vector<size_type> &,
620  const std::vector<size_type> &,
621  const unsigned int,
622  const bool);
623  template void
625  const std::vector<size_type> &,
626  const std::vector<size_type> &,
627  const unsigned int,
628  const bool);
629 
630  template void
632  do_reinit (const IndexSet &,
633  const IndexSet &,
634  const SparsityPattern &);
635 
636  template void
638  do_reinit (const IndexSet &,
639  const IndexSet &,
640  const DynamicSparsityPattern &);
641 
642 
643  PetscScalar
645  {
646  Vector tmp (v);
647  vmult (tmp, v);
648  // note, that v*tmp returns sum_i conjugate(v)_i * tmp_i
649  return v*tmp;
650  }
651 
652  PetscScalar
654  const Vector &v) const
655  {
656  Vector tmp (v);
657  vmult (tmp, v);
658  // note, that v*tmp returns sum_i conjugate(v)_i * tmp_i
659  return u*tmp;
660  }
661 
662  IndexSet
664  {
665  PetscInt n_rows, n_cols, n_loc_rows, n_loc_cols, min, max;
666  PetscErrorCode ierr;
667 
668  ierr = MatGetSize (matrix, &n_rows, &n_cols);
669  AssertThrow (ierr == 0, ExcPETScError(ierr));
670 
671  ierr = MatGetLocalSize(matrix, &n_loc_rows, &n_loc_cols);
672  AssertThrow (ierr == 0, ExcPETScError(ierr));
673 
674  ierr = MatGetOwnershipRangeColumn(matrix, &min, &max);
675  AssertThrow (ierr == 0, ExcPETScError(ierr));
676 
677  Assert(n_loc_cols==max-min, ExcMessage("PETSc is requiring non contiguous memory allocation."));
678 
679  IndexSet indices(n_cols);
680  indices.add_range(min, max);
681  indices.compress();
682 
683  return indices;
684  }
685 
686  IndexSet
688  {
689  PetscInt n_rows, n_cols, n_loc_rows, n_loc_cols, min, max;
690  PetscErrorCode ierr;
691 
692  ierr = MatGetSize (matrix, &n_rows, &n_cols);
693  AssertThrow (ierr == 0, ExcPETScError(ierr));
694 
695  ierr = MatGetLocalSize(matrix, &n_loc_rows, &n_loc_cols);
696  AssertThrow (ierr == 0, ExcPETScError(ierr));
697 
698  ierr = MatGetOwnershipRange(matrix, &min, &max);
699  AssertThrow (ierr == 0, ExcPETScError(ierr));
700 
701  Assert(n_loc_rows==max-min, ExcMessage("PETSc is requiring non contiguous memory allocation."));
702 
703  IndexSet indices(n_rows);
704  indices.add_range(min, max);
705  indices.compress();
706 
707  return indices;
708  }
709 
710  void
712  const SparseMatrix &B,
713  const MPI::Vector &V) const
714  {
715  // Simply forward to the protected member function of the base class
716  // that takes abstract matrix and vector arguments (to which the compiler
717  // automatically casts the arguments).
718  MatrixBase::mmult (C, B, V);
719  }
720 
721  void
723  const SparseMatrix &B,
724  const MPI::Vector &V) const
725  {
726  // Simply forward to the protected member function of the base class
727  // that takes abstract matrix and vector arguments (to which the compiler
728  // automatically casts the arguments).
729  MatrixBase::Tmmult (C, B, V);
730  }
731 
732  }
733 }
734 
735 
736 DEAL_II_NAMESPACE_CLOSE
737 
738 #endif // DEAL_II_WITH_PETSC
static ::ExceptionBase & ExcLocalRowsTooLarge(int arg1, int arg2)
PetscErrorCode destroy_matrix(Mat &matrix)
void Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
void copy_from(const SparseMatrix &other)
size_type nth_index_in_set(const unsigned int local_index) const
Definition: index_set.h:1769
void vmult(VectorBase &dst, const VectorBase &src) const
void do_reinit(const size_type m, const size_type n, const size_type local_rows, const size_type local_columns, const size_type n_nonzero_per_row, const bool is_symmetric=false, const size_type n_offdiag_nonzero_per_row=0)
size_type row_length(const size_type row) const
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:107
void set_matrix_option(Mat &matrix, const MatOption option_name, const PetscBool option_value=PETSC_FALSE)
PetscBool is_symmetric(const double tolerance=1.e-12)
bool is_ascending_and_one_to_one(const MPI_Comm &communicator) const
Definition: index_set.cc:618
size_type size() const
Definition: index_set.h:1575
void compress(const VectorOperation::values operation)
void mmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
MatrixBase & operator=(const MatrixBase &)=delete
static ::ExceptionBase & ExcMessage(std::string arg1)
SparseMatrix & operator=(const value_type d)
PetscScalar matrix_scalar_product(const Vector &u, const Vector &v) const
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
types::global_dof_index size_type
void set_keep_zero_rows(Mat &matrix)
void reinit(const MPI_Comm &communicator, const size_type m, const size_type n, const size_type local_rows, const size_type local_columns, const size_type n_nonzero_per_row, const bool is_symmetric=false, const size_type n_offdiag_nonzero_per_row=0)
void add_range(const size_type begin, const size_type end)
Definition: index_set.cc:98
void compress() const
Definition: index_set.h:1584
void Tmmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
bool is_contiguous() const
Definition: index_set.h:1698
PetscScalar matrix_norm_square(const Vector &v) const
static ::ExceptionBase & ExcNotImplemented()
size_type n_elements() const
Definition: index_set.h:1717
static ::ExceptionBase & ExcInternalError()
void close_matrix(Mat &matrix)