*/
BlockSparseMatrix() = default;
+ /**
+ * Create a BlockSparseMatrix with a PETSc Mat
+ */
+ explicit BlockSparseMatrix(const Mat &);
+
/**
* Destructor.
*/
Mat &
petsc_matrix();
+ /**
+ * This method assigns the PETSc Mat to the instance of the class.
+ */
+ void
+ assign_petsc_matrix(Mat A);
+
private:
Mat petsc_nest_matrix = nullptr;
};
// ------------- inline and template functions -----------------
+ inline BlockSparseMatrix::BlockSparseMatrix(const Mat &A)
+ : BlockSparseMatrix()
+ {
+ this->assign_petsc_matrix(A);
+ }
+
inline BlockSparseMatrix &
BlockSparseMatrix::operator=(const double d)
{
*/
virtual ~MatrixBase() override;
+ /**
+ * This method assignes the PETSc Mat to the instance of the class.
+ *
+ */
+ void
+ assign_petsc_matrix(Mat A);
+
/**
* This operator assigns a scalar to a matrix. Since this does usually not
* make much sense (should we set all matrix entries to this value? Only
*/
SparseMatrix();
+ /**
+ * Initialize a Matrix from a PETSc Mat object. Note that we do not copy
+ * the matrix.
+ */
+ explicit SparseMatrix(const Mat &);
+
/**
* Create a sparse matrix of dimensions @p m times @p n, with an initial
* guess of @p n_nonzero_per_row nonzero elements per row. PETSc is able
*/
SparseMatrix();
+ /**
+ * Initialize a SparseMatrix from a PETSc Mat object. Note that we do not
+ * copy the matrix.
+ */
+ explicit SparseMatrix(const Mat &);
+
/**
* Destructor to free the PETSc object.
*/
AssertThrow(ierr == 0, ExcPETScError(ierr));
}
+ void
+ MatrixBase::assign_petsc_matrix(Mat A)
+ {
+ AssertThrow(last_action == ::dealii::VectorOperation::unknown,
+ ExcMessage("Cannot assign a new Mat"));
+ PetscErrorCode ierr =
+ PetscObjectReference(reinterpret_cast<PetscObject>(A));
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ destroy_matrix(matrix);
+ matrix = A;
+ }
MatrixBase::~MatrixBase()
{
destroy_matrix(matrix);
}
-
-
void
MatrixBase::clear()
{
return petsc_nest_matrix;
}
+ void
+ BlockSparseMatrix::assign_petsc_matrix(Mat A)
+ {
+ clear();
+
+ PetscBool isnest;
+ PetscInt nr = 1, nc = 1;
+
+ PetscErrorCode ierr =
+ PetscObjectTypeCompare(reinterpret_cast<PetscObject>(A),
+ MATNEST,
+ &isnest);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ std::vector<Mat> mats;
+ if (isnest)
+ {
+ ierr = MatNestGetSize(A, &nr, &nc);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ for (PetscInt i = 0; i < nr; ++i)
+ {
+ for (PetscInt j = 0; j < nc; ++j)
+ {
+ Mat sA;
+ ierr = MatNestGetSubMat(A, i, j, &sA);
+ mats.push_back(sA);
+ }
+ }
+ }
+ else
+ {
+ mats.push_back(A);
+ }
+
+ std::vector<size_type> r_block_sizes(nr, 0);
+ std::vector<size_type> c_block_sizes(nc, 0);
+ this->row_block_indices.reinit(r_block_sizes);
+ this->column_block_indices.reinit(c_block_sizes);
+ this->sub_objects.reinit(nr, nc);
+ for (PetscInt i = 0; i < nr; ++i)
+ {
+ for (PetscInt j = 0; j < nc; ++j)
+ {
+ // TODO: MATNEST supports NULL blocks
+ this->sub_objects[i][j] = new BlockType(mats[i * nc + j]);
+ }
+ }
+
+ collect_sizes();
+ }
+
} // namespace MPI
} // namespace PETScWrappers
AssertThrow(ierr == 0, ExcPETScError(ierr));
}
+ SparseMatrix::SparseMatrix(const Mat &A)
+ : MatrixBase(A)
+ {}
SparseMatrix::~SparseMatrix()
{
AssertThrow(ierr == 0, ExcPETScError(ierr));
}
-
+ SparseMatrix::SparseMatrix(const Mat &A)
+ : MatrixBase(A)
+ {}
SparseMatrix::SparseMatrix(const size_type m,
const size_type n,
// Extract the PETSc MATNEST and use print from PETScWrappers::MatrixBase
PETScWrappers::MatrixBase tmp(pbsm.petsc_matrix());
tmp.print(deallog.get_file_stream());
+
+ // Extract the PETSc MATNEST and assign to a new BlockSparseMatrix
+ PETScWrappers::MPI::BlockSparseMatrix tmp2(pbsm.petsc_matrix());
+ Assert(tmp2.n_block_rows() == pbsm.n_block_rows(), ExcInternalError());
+ Assert(tmp2.n_block_cols() == pbsm.n_block_cols(), ExcInternalError());
+ Assert(tmp2.m() == pbsm.m(), ExcInternalError());
+ Assert(tmp2.n() == pbsm.n(), ExcInternalError());
+ for (unsigned int blr = 0; blr < 2; ++blr)
+ {
+ for (unsigned int blc = 0; blc < 2; ++blc)
+ {
+ Assert(tmp2.block(blr, blc).m() == pbsm.block(blr, blc).m(),
+ ExcInternalError());
+ Assert(tmp2.block(blr, blc).n() == pbsm.block(blr, blc).n(),
+ ExcInternalError());
+ Assert(tmp2.block(blr, blc).petsc_matrix() ==
+ pbsm.block(blr, blc).petsc_matrix(),
+ ExcInternalError());
+ }
+ }
}