I am running a simulation with MPI in parallel. I would like to retrieve on one single process the submatrix containing the owned dofs and the ghost ones. Simply doing
If you don’t mind throwing the kitchen sink at it, something like
def to_numpy_matrix(mat: petsc4py.PETSc.Mat) -> np.typing.NDArray[ # type: ignore[no-any-unimported]
petsc4py.PETSc.ScalarType]:
"""Convert distributed PETSc Mat to a dense allgather-ed numpy matrix."""
ai, aj, av = mat.getValuesCSR()
local_np_mat = scipy.sparse.csr_matrix((av, aj, ai), shape=(mat.getLocalSize()[0], mat.getSize()[1])).toarray()
comm = mat.getComm().tompi4py()
return np.vstack(comm.allgather(local_np_mat))
should work.
If you want to preserve performance:
you should not convert to a dense numpy matrix, but stick with scipy sparse format
comm.allgather should be replaced with specific requests to the process owning the dofs, and sending/receiving only the very few ghost rows, but I don’t have a snippet ready for that.