16 #ifndef dealii_petsc_matrix_base_h 17 #define dealii_petsc_matrix_base_h 20 #include <deal.II/base/config.h> 22 #ifdef DEAL_II_WITH_PETSC 24 # include <deal.II/base/subscriptor.h> 25 # include <deal.II/lac/exceptions.h> 26 # include <deal.II/lac/full_matrix.h> 27 # include <deal.II/lac/petsc_compatibility.h> 28 # include <deal.II/lac/vector_operation.h> 29 # include <deal.II/lac/petsc_vector_base.h> 31 # include <petscmat.h> 37 DEAL_II_NAMESPACE_OPEN
47 namespace MatrixIterators
103 PetscScalar
value()
const;
114 <<
"You tried to access row " << arg1
115 <<
" of a distributed matrix, but only rows " 116 << arg2 <<
" through " << arg3
117 <<
" are stored locally and can be accessed.");
223 <<
"Attempt to access element " << arg2
224 <<
" of row " << arg1
225 <<
" which doesn't have that many elements.");
339 const PetscScalar value);
360 void set (
const std::vector<size_type> &indices,
362 const bool elide_zero_values =
false);
369 void set (
const std::vector<size_type> &row_indices,
370 const std::vector<size_type> &col_indices,
372 const bool elide_zero_values =
false);
389 const std::vector<size_type > &col_indices,
390 const std::vector<PetscScalar> &values,
391 const bool elide_zero_values =
false);
410 const PetscScalar *values,
411 const bool elide_zero_values =
false);
424 const PetscScalar value);
445 void add (
const std::vector<size_type> &indices,
447 const bool elide_zero_values =
true);
454 void add (
const std::vector<size_type> &row_indices,
455 const std::vector<size_type> &col_indices,
457 const bool elide_zero_values =
true);
474 const std::vector<size_type> &col_indices,
475 const std::vector<PetscScalar> &values,
476 const bool elide_zero_values =
true);
495 const PetscScalar *values,
496 const bool elide_zero_values =
true,
497 const bool col_indices_are_sorted =
false);
516 const PetscScalar new_diag_value = 0);
526 void clear_rows (
const std::vector<size_type> &rows,
527 const PetscScalar new_diag_value = 0);
605 std::pair<size_type, size_type>
699 PetscScalar
trace ()
const;
727 const PetscScalar factor);
840 operator Mat ()
const;
875 void write_ascii (
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
884 void print (std::ostream &out,
885 const bool alternative_output =
false)
const;
896 "You are attempting an operation on two matrices that " 897 "are the same object, but the operation requires that the " 898 "two objects are in fact different.");
905 <<
"You tried to do a " 910 <<
" operation but the matrix is currently in " 915 <<
" mode. You first have to call 'compress()'.");
1032 template <
class>
friend class ::BlockMatrixBase;
1041 namespace MatrixIterators
1047 const size_type row,
1048 const size_type index)
1050 matrix(const_cast<MatrixBase *>(matrix)),
1054 visit_present_row ();
1073 return (*colnum_cache)[a_index];
1091 return (*value_cache)[a_index];
1108 const_iterator::operator++ ()
1116 if (accessor.a_index >= accessor.colnum_cache->size())
1118 accessor.a_index = 0;
1121 while ((accessor.a_row < accessor.matrix->m())
1123 (accessor.a_row < accessor.matrix->local_range().second)
1125 (accessor.matrix->row_length(accessor.a_row) == 0))
1128 accessor.visit_present_row();
1136 const_iterator::operator++ (
int)
1138 const const_iterator old_state = *
this;
1145 const const_iterator::Accessor &
1153 const const_iterator::Accessor *
1154 const_iterator::operator-> ()
const 1163 operator == (
const const_iterator &other)
const 1165 return (accessor.a_row == other.accessor.a_row &&
1166 accessor.a_index == other.accessor.a_index);
1173 operator != (
const const_iterator &other)
const 1175 return ! (*
this == other);
1182 operator < (
const const_iterator &other)
const 1184 return (accessor.row() < other.accessor.row() ||
1185 (accessor.row() == other.accessor.row() &&
1186 accessor.index() < other.accessor.index()));
1202 MatrixBase::set (
const size_type i,
1204 const PetscScalar value)
1208 set (i, 1, &j, &value,
false);
1215 MatrixBase::set (
const std::vector<size_type> &indices,
1217 const bool elide_zero_values)
1219 Assert (indices.size() == values.
m(),
1223 for (size_type i=0; i<indices.size(); ++i)
1224 set (indices[i], indices.size(), indices.data(), &values(i,0),
1232 MatrixBase::set (
const std::vector<size_type> &row_indices,
1233 const std::vector<size_type> &col_indices,
1235 const bool elide_zero_values)
1237 Assert (row_indices.size() == values.
m(),
1239 Assert (col_indices.size() == values.
n(),
1242 for (size_type i=0; i<row_indices.size(); ++i)
1243 set (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1251 MatrixBase::set (
const size_type row,
1252 const std::vector<size_type> &col_indices,
1253 const std::vector<PetscScalar> &values,
1254 const bool elide_zero_values)
1256 Assert (col_indices.size() == values.size(),
1259 set (row, col_indices.size(), col_indices.data(), values.data(),
1267 MatrixBase::set (
const size_type row,
1268 const size_type n_cols,
1269 const size_type *col_indices,
1270 const PetscScalar *values,
1271 const bool elide_zero_values)
1275 const PetscInt petsc_i = row;
1276 PetscInt
const *col_index_ptr;
1278 PetscScalar
const *col_value_ptr;
1282 if (elide_zero_values ==
false)
1284 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1285 col_value_ptr = values;
1292 if (column_indices.size() < n_cols)
1294 column_indices.resize(n_cols);
1295 column_values.resize(n_cols);
1299 for (size_type j=0; j<n_cols; ++j)
1301 const PetscScalar value = values[j];
1303 if (value != PetscScalar())
1305 column_indices[n_columns] = col_indices[j];
1306 column_values[n_columns] = value;
1312 col_index_ptr = column_indices.data();
1313 col_value_ptr = column_values.data();
1316 const PetscErrorCode ierr = MatSetValues (matrix, 1, &petsc_i, n_columns,
1318 col_value_ptr, INSERT_VALUES);
1326 MatrixBase::add (
const size_type i,
1328 const PetscScalar value)
1333 if (value == PetscScalar())
1344 add (i, 1, &j, &value,
false);
1351 MatrixBase::add (
const std::vector<size_type> &indices,
1353 const bool elide_zero_values)
1355 Assert (indices.size() == values.
m(),
1359 for (size_type i=0; i<indices.size(); ++i)
1360 add (indices[i], indices.size(), indices.data(), &values(i,0),
1368 MatrixBase::add (
const std::vector<size_type> &row_indices,
1369 const std::vector<size_type> &col_indices,
1371 const bool elide_zero_values)
1373 Assert (row_indices.size() == values.
m(),
1375 Assert (col_indices.size() == values.
n(),
1378 for (size_type i=0; i<row_indices.size(); ++i)
1379 add (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1387 MatrixBase::add (
const size_type row,
1388 const std::vector<size_type> &col_indices,
1389 const std::vector<PetscScalar> &values,
1390 const bool elide_zero_values)
1392 Assert (col_indices.size() == values.size(),
1395 add (row, col_indices.size(), col_indices.data(), values.data(),
1403 MatrixBase::add (
const size_type row,
1404 const size_type n_cols,
1405 const size_type *col_indices,
1406 const PetscScalar *values,
1407 const bool elide_zero_values,
1410 (void)elide_zero_values;
1414 const PetscInt petsc_i = row;
1415 PetscInt
const *col_index_ptr;
1417 PetscScalar
const *col_value_ptr;
1421 if (elide_zero_values ==
false)
1423 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1424 col_value_ptr = values;
1431 if (column_indices.size() < n_cols)
1433 column_indices.resize(n_cols);
1434 column_values.resize(n_cols);
1438 for (size_type j=0; j<n_cols; ++j)
1440 const PetscScalar value = values[j];
1442 if (value != PetscScalar())
1444 column_indices[n_columns] = col_indices[j];
1445 column_values[n_columns] = value;
1451 col_index_ptr = column_indices.data();
1452 col_value_ptr = column_values.data();
1455 const PetscErrorCode ierr = MatSetValues (matrix, 1, &petsc_i, n_columns,
1456 col_index_ptr, col_value_ptr,
1468 MatrixBase::operator() (
const size_type i,
1469 const size_type j)
const 1477 MatrixBase::const_iterator
1478 MatrixBase::begin()
const 1480 return const_iterator(
this, 0, 0);
1485 MatrixBase::const_iterator
1486 MatrixBase::end()
const 1488 return const_iterator(
this, m(), 0);
1493 MatrixBase::const_iterator
1494 MatrixBase::begin(
const size_type r)
const 1496 Assert (in_local_range(r),
1497 ExcIndexRange(r, local_range().first, local_range().second));
1499 if (row_length(r) > 0)
1500 return const_iterator(
this, r, 0);
1507 MatrixBase::const_iterator
1508 MatrixBase::end(
const size_type r)
const 1510 Assert (in_local_range(r),
1511 ExcIndexRange(r, local_range().first, local_range().second));
1523 for (size_type i=r+1; i<m(); ++i)
1524 if (i == local_range().second || (row_length(i) > 0))
1525 return const_iterator(
this, i, 0);
1536 MatrixBase::in_local_range (
const size_type index)
const 1538 PetscInt begin, end;
1540 const PetscErrorCode ierr = MatGetOwnershipRange (static_cast<const Mat &>(matrix),
1544 return ((index >= static_cast<size_type>(begin)) &&
1545 (index < static_cast<size_type>(end)));
1555 last_action = new_action;
1557 Assert (last_action == new_action, ExcWrongMode (last_action, new_action));
1564 MatrixBase::assert_is_compressed ()
1569 ExcMessage(
"Error: missing compress() call."));
1576 MatrixBase::prepare_add()
1585 MatrixBase::prepare_set()
1594 DEAL_II_NAMESPACE_CLOSE
1597 #endif // DEAL_II_WITH_PETSC types::global_dof_index size_type
#define DeclException2(Exception2, type1, type2, outsequence)
bool operator==(const const_iterator &) const
void Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
Contents is actually a matrix.
PetscScalar matrix_scalar_product(const VectorBase &u, const VectorBase &v) const
static ::ExceptionBase & ExcBeyondEndOfMatrix()
void add(const size_type i, const size_type j, const PetscScalar value)
void vmult(VectorBase &dst, const VectorBase &src) const
const_iterator begin() const
PetscReal frobenius_norm() const
static ::ExceptionBase & ExcInvalidIndexWithinRow(int arg1, int arg2)
std::shared_ptr< const std::vector< PetscScalar > > value_cache
const Accessor & operator*() const
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< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
PetscBool is_symmetric(const double tolerance=1.e-12)
PetscBool is_hermitian(const double tolerance=1.e-12)
void clear_rows(const std::vector< size_type > &rows, const PetscScalar new_diag_value=0)
PetscReal linfty_norm() const
std::vector< PetscInt > column_indices
const_iterator(const MatrixBase *matrix, const size_type row, const size_type index)
void compress(const VectorOperation::values operation)
types::global_dof_index size_type
std::vector< PetscScalar > column_values
MatrixIterators::const_iterator const_iterator
size_type n_nonzero_elements() const
MatrixBase & operator=(const MatrixBase &)=delete
static ::ExceptionBase & ExcMessage(std::string arg1)
size_type local_size() const
unsigned int global_dof_index
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)
#define DeclException0(Exception0)
void vmult_add(VectorBase &dst, const VectorBase &src) const
PetscScalar residual(VectorBase &dst, const VectorBase &x, const VectorBase &b) const
void mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
types::global_dof_index size_type
PetscScalar diag_element(const size_type i) const
void Tvmult(VectorBase &dst, const VectorBase &src) const
PetscScalar el(const size_type i, const size_type j) const
void Tvmult_add(VectorBase &dst, const VectorBase &src) const
const_iterator end() const
PetscScalar operator()(const size_type i, const size_type j) const
std::shared_ptr< const std::vector< size_type > > colnum_cache
static ::ExceptionBase & ExcIteratorPastEnd()
void print(std::ostream &out, const bool alternative_output=false) const
static ::ExceptionBase & ExcNotQuadratic()
void write_ascii(const PetscViewerFormat format=PETSC_VIEWER_DEFAULT)
VectorOperation::values last_action
void prepare_action(const VectorOperation::values new_action)
const_iterator & operator++()
bool in_local_range(const size_type index) const
MatrixBase & operator*=(const PetscScalar factor)
PetscScalar value() const
std::pair< size_type, size_type > local_range() const
static ::ExceptionBase & ExcAccessToNonlocalRow(int arg1, int arg2, int arg3)
PetscScalar trace() const
PetscScalar matrix_norm_square(const VectorBase &v) const
MatrixBase & operator/=(const PetscScalar factor)
PetscReal l1_norm() const
static ::ExceptionBase & ExcSourceEqualsDestination()
static ::ExceptionBase & ExcWrongMode(int arg1, int arg2)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
bool operator!=(const const_iterator &) const
static ::ExceptionBase & ExcBeyondEndOfMatrix()
virtual const MPI_Comm & get_mpi_communicator() const =0
#define AssertIsFinite(number)
void clear_row(const size_type row, const PetscScalar new_diag_value=0)
std::size_t memory_consumption() const
void assert_is_compressed()
static ::ExceptionBase & ExcInternalError()