16 #ifndef dealii_petsc_matrix_base_h 17 # define dealii_petsc_matrix_base_h 22 # ifdef DEAL_II_WITH_PETSC 32 # include <petscmat.h> 42 template <
typename Matrix>
52 namespace MatrixIterators
125 <<
"You tried to access row " << arg1
126 <<
" of a distributed matrix, but only rows " << arg2
127 <<
" through " << arg3
128 <<
" are stored locally and can be accessed.");
239 <<
"Attempt to access element " << arg2 <<
" of row " 240 << arg1 <<
" which doesn't have that many elements.");
377 set(
const std::vector<size_type> & indices,
379 const bool elide_zero_values =
false);
387 set(
const std::vector<size_type> & row_indices,
388 const std::vector<size_type> & col_indices,
390 const bool elide_zero_values =
false);
408 const std::vector<size_type> & col_indices,
409 const std::vector<PetscScalar> &values,
410 const bool elide_zero_values =
false);
430 const PetscScalar *values,
431 const bool elide_zero_values =
false);
465 add(
const std::vector<size_type> & indices,
467 const bool elide_zero_values =
true);
475 add(
const std::vector<size_type> & row_indices,
476 const std::vector<size_type> & col_indices,
478 const bool elide_zero_values =
true);
496 const std::vector<size_type> & col_indices,
497 const std::vector<PetscScalar> &values,
498 const bool elide_zero_values =
true);
518 const PetscScalar *values,
519 const bool elide_zero_values =
true,
520 const bool col_indices_are_sorted =
false);
539 clear_row(
const size_type row,
const PetscScalar new_diag_value = 0);
550 clear_rows(
const std::vector<size_type> &rows,
551 const PetscScalar new_diag_value = 0);
634 std::pair<size_type, size_type>
648 virtual const MPI_Comm &
649 get_mpi_communicator()
const = 0;
657 n_nonzero_elements()
const;
690 frobenius_norm()
const;
713 matrix_norm_square(
const VectorBase &v)
const;
743 operator*=(
const PetscScalar factor);
749 operator/=(
const PetscScalar factor);
757 add(
const PetscScalar factor,
const MatrixBase &other);
767 add(
const MatrixBase &other,
const PetscScalar factor);
887 operator Mat()
const;
908 is_symmetric(
const double tolerance = 1.
e-12);
916 is_hermitian(
const double tolerance = 1.
e-12);
925 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
935 print(std::ostream &out,
const bool alternative_output =
false)
const;
947 "You are attempting an operation on two matrices that " 948 "are the same object, but the operation requires that the " 949 "two objects are in fact different.");
957 <<
"You tried to do a " 958 << (arg1 == 1 ?
"'set'" : (arg1 == 2 ?
"'add'" :
"???"))
959 <<
" operation but the matrix is currently in " 960 << (arg2 == 1 ?
"'set'" : (arg2 == 2 ?
"'add'" :
"???"))
961 <<
" mode. You first have to call 'compress()'.");
989 assert_is_compressed();
1078 friend class ::BlockMatrixBase;
1087 namespace MatrixIterators
1092 :
matrix(const_cast<MatrixBase *>(matrix))
1198 return !(*
this == other);
1226 set(i, 1, &j, &
value,
false);
1234 const bool elide_zero_values)
1236 Assert(indices.size() == values.
m(),
1240 for (
size_type i = 0; i < indices.size(); ++i)
1252 const std::vector<size_type> & col_indices,
1254 const bool elide_zero_values)
1256 Assert(row_indices.size() == values.
m(),
1258 Assert(col_indices.size() == values.
n(),
1261 for (
size_type i = 0; i < row_indices.size(); ++i)
1273 const std::vector<size_type> & col_indices,
1274 const std::vector<PetscScalar> &values,
1275 const bool elide_zero_values)
1277 Assert(col_indices.size() == values.size(),
1293 const PetscScalar *values,
1294 const bool elide_zero_values)
1298 const PetscInt petsc_i =
row;
1299 PetscInt
const *col_index_ptr;
1301 PetscScalar
const *col_value_ptr;
1305 if (elide_zero_values ==
false)
1307 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1308 col_value_ptr = values;
1315 if (column_indices.size() < n_cols)
1317 column_indices.resize(n_cols);
1318 column_values.resize(n_cols);
1324 const PetscScalar value = values[j];
1326 if (value != PetscScalar())
1328 column_indices[n_columns] = col_indices[j];
1329 column_values[n_columns] =
value;
1335 col_index_ptr = column_indices.data();
1336 col_value_ptr = column_values.data();
1339 const PetscErrorCode ierr = MatSetValues(
matrix,
1356 if (value == PetscScalar())
1367 add(i, 1, &j, &value,
false);
1375 const bool elide_zero_values)
1377 Assert(indices.size() == values.
m(),
1381 for (
size_type i = 0; i < indices.size(); ++i)
1393 const std::vector<size_type> & col_indices,
1395 const bool elide_zero_values)
1397 Assert(row_indices.size() == values.
m(),
1399 Assert(col_indices.size() == values.
n(),
1402 for (
size_type i = 0; i < row_indices.size(); ++i)
1414 const std::vector<size_type> & col_indices,
1415 const std::vector<PetscScalar> &values,
1416 const bool elide_zero_values)
1418 Assert(col_indices.size() == values.size(),
1434 const PetscScalar *values,
1435 const bool elide_zero_values,
1438 (void)elide_zero_values;
1442 const PetscInt petsc_i =
row;
1443 PetscInt
const *col_index_ptr;
1445 PetscScalar
const *col_value_ptr;
1449 if (elide_zero_values ==
false)
1451 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1452 col_value_ptr = values;
1459 if (column_indices.size() < n_cols)
1461 column_indices.resize(n_cols);
1462 column_values.resize(n_cols);
1468 const PetscScalar value = values[j];
1470 if (value != PetscScalar())
1472 column_indices[n_columns] = col_indices[j];
1473 column_values[n_columns] =
value;
1479 col_index_ptr = column_indices.data();
1480 col_value_ptr = column_values.data();
1483 const PetscErrorCode ierr = MatSetValues(
1484 matrix, 1, &petsc_i, n_columns, col_index_ptr, col_value_ptr, ADD_VALUES);
1502 (in_local_range(0) && in_local_range(m() - 1)),
1504 "begin() and end() can only be called on a processor owning the entire matrix. If this is a distributed matrix, use begin(row) and end(row) instead."));
1509 while ((first_nonempty_row < m()) && (row_length(first_nonempty_row) == 0))
1510 ++first_nonempty_row;
1520 (in_local_range(0) && in_local_range(m() - 1)),
1522 "begin() and end() can only be called on a processor owning the entire matrix. If this is a distributed matrix, use begin(row) and end(row) instead."));
1531 Assert(in_local_range(r),
1534 if (row_length(r) > 0)
1544 Assert(in_local_range(r),
1558 if (i == local_range().second || (row_length(i) > 0))
1565 return {
this, m(), 0};
1575 const PetscErrorCode ierr =
1576 MatGetOwnershipRange(static_cast<const Mat &>(
matrix), &begin, &end);
1579 return ((index >= static_cast<size_type>(begin)) &&
1580 (index < static_cast<size_type>(end)));
1589 last_action = new_action;
1591 Assert(last_action == new_action, ExcWrongMode(last_action, new_action));
1602 ExcMessage(
"Error: missing compress() call."));
1628 # endif // DEAL_II_WITH_PETSC
#define DeclException2(Exception2, type1, type2, outsequence)
bool operator==(const const_iterator &) const
void add(const size_type i, const size_type j, const PetscScalar value)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
const_iterator begin() const
static ::ExceptionBase & ExcInvalidIndexWithinRow(int arg1, int arg2)
std::shared_ptr< const std::vector< PetscScalar > > value_cache
const Accessor & operator*() const
#define AssertIndexRange(index, range)
const Accessor * operator->() const
size_type row_length(const size_type row) const
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
std::vector< PetscInt > column_indices
const_iterator(const MatrixBase *matrix, const size_type row, const size_type index)
std::vector< PetscScalar > column_values
static ::ExceptionBase & ExcMessage(std::string arg1)
std::string compress(const std::string &input)
Accessor(const MatrixBase *matrix, const size_type row, const size_type index)
bool operator<(const const_iterator &) const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DeclExceptionMsg(Exception, defaulttext)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
#define DeclException0(Exception0)
#define DEAL_II_NAMESPACE_CLOSE
VectorType::value_type * end(VectorType &V)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
const_iterator end() const
PetscScalar operator()(const size_type i, const size_type j) const
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
std::shared_ptr< const std::vector< size_type > > colnum_cache
static ::ExceptionBase & ExcIteratorPastEnd()
friend class const_iterator
static ::ExceptionBase & ExcNotQuadratic()
VectorOperation::values last_action
void prepare_action(const VectorOperation::values new_action)
unsigned int global_dof_index
const_iterator & operator++()
bool in_local_range(const size_type index) const
PetscScalar value() const
std::pair< size_type, size_type > local_range() const
static ::ExceptionBase & ExcAccessToNonlocalRow(int arg1, int arg2, int arg3)
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
Number l1_norm(const Tensor< 2, dim, Number > &t)
void set(const size_type i, const size_type j, const PetscScalar value)
constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
bool operator!=(const const_iterator &) const
static ::ExceptionBase & ExcBeyondEndOfMatrix()
#define DEAL_II_DEPRECATED
#define AssertIsFinite(number)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void assert_is_compressed()