Hello everyone,
We want to compress a PETScMatrix such that zero rows-colums are eliminated, but not the internal zeros which are located on non-zero rows-colums. In a context, this matrix can be any of the stiffness or mass matrix in a generalized eigenvalue problem.
Therefore, I give a minimal working example (MWE) in which a 32 by 32 Numpy matrix is created so that non-zero entries are one. Then, it is converted to a PETScMatrix instance.
This compression operation can be done with Numpy array slicing, etc. Yet, we are in
need of using PETSc functions, since the matrix might be large enough for a Numpy matrix
which may occupy lots of memory.
Unfortunately, we could not find a resource to this with PETSc functions, thus any
suggestion and/or implementation will be welcomed.
Note: If you want to visualize sparsity of the example matrix, you can uncomment the last
portion of the script. Nevertheless, I have given the figure of the same matrix for
presentation after the script.
MWE:
from fenics import *
import petsc4py.PETSc as pet
import numpy as np
import matplotlib.pyplot as plt
# For the sake of argument, create a numpy matrix
# with some rows & colums are zero:
A = np.ones((32, 32))
# Assign some zero entries
A[[3,9,23,18,24,6,22], [6,4,18,25,27,24,6]] = 0
A[[6,4,18,25,27,24,6], [3,9,23,18,24,6,22]] = 0
A[[2,4,8,12,16,20,30],:] = 0
A[:,[2,4,8,12,16,20,30]] = 0
# Now, create B matrix with petsc4py. Only used for
# prior to creating its PETScMatrix version.
B = pet.Mat().create()
B.setSizes(A.shape)
B.setType('aij')
B.setUp()
# Set values of petsc4py matrix and assemble
B.setValues(range(0, A.shape[0]), range(0, A.shape[0]), A)
B.assemble()
# Now, use PETScMatrix from fenics to convert it
B = PETScMatrix(B)
# Sparsity plot (uncomment if you want)
#fig, ax = plt.subplots()
#img = ax.spy(B.array())
#ax.set_title("Visualization of the example matrix")
#plt.xticks([]); plt.yticks([])
#plt.savefig("B.png", bbox_inches='tight')
Best,
Ufuk
OS: Archlinux
FEniCS Docker image: 2019.1.0