This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Sparse matrix in DOLFIN with C++

+1 vote

I'm assembling a dolfin::Matrix in C++ but if I try to access the matrix sparse pattern using the data() method I've seen that it is not yet available with DOLFIN 1.2.0.
Is there any other way in which one can know the number of non zero entries ?

asked Jul 29, 2013 by gedeone FEniCS User (1,110 points)
edited Aug 6, 2013 by Garth N. Wells

I realized that to access the sparsity pattern of the matrix one has to specify the linear algebra backend.. for example the following seems to work:

dolfin::parameters["linear_algebra_backend"] = "uBLAS";
dolfin::Matrix A;
....
boost::tuples::tuple<const std::size_t*, const std::size_t*, const double*, int> aa = A.data ();

3 Answers

+1 vote
 
Best answer

There seems to be few not optimal options:

  • SparsityPattern::num_nonzeros() could be useful. Unfortunately it seems that sparsity pattern can't be extracted or built from existing Matrix. You can propose some enhancement.

  • You can parse output of PETScMatrix::str(true)

  • Probably the best solution would be to call some PETSc routine on PETScMatrix::mat()

answered Aug 8, 2013 by Jan Blechta FEniCS Expert (51,420 points)
selected Aug 24, 2013 by gedeone
0 votes

I haven't worked with the dolfin matrix class yet. So I am not sure, what is the origin of your matrix. However, if your matrix is a representation of a linear form, you can consider using scipy.sparse matrices that will give you all information on the pattern and so on. The matrix representation of a weak Laplacian can be obtained like

from dolfin import *
import scipy.sparse as sps
parameters.linear_algebra_backend = "uBLAS"

mesh = UnitSquareMesh(4,4)
V = VectorFunctionSpace(mesh, "CG", 2)

u = TrialFunction(V)
v = TestFunction(V)
a = inner(grad(u), grad(v))*dx

# Assemble the system
A = assemble(aa)

# Convert DOLFIN representation to scipy sparse arrays
rows, cols, values = A.data()
Aa = sps.csr_matrix((values, cols, rows))
answered Jul 29, 2013 by Jan FEniCS User (8,290 points)

Thanks for your answer, but I'm using C++ where unfortunately the method data() or sparray are not available. I have corrected now my question.

+2 votes

You can access the non-zero entries of a row using GenericMatrix::getrow, which also get the column indices of the non-zero entries in the row.

Being able to get the number of non zeroes depends on the backend providing the functionality. Using the SparsityPattern used for matrix initialisation is not reliable because some backends, e.g. PETSc, may do some further compression.

answered Aug 12, 2013 by Garth N. Wells FEniCS Expert (35,930 points)

I just need an estimation of the nnz entry. So even if PETSc do some further backends I don't really care. But I don't see how to use SparsityPattern.

I'm doing something like

const dolfin::Form & a = ...;
dolfin::Matrix A();
dolfin::assemble (A, a);
int nnz = ?????

Thanks

Marco

...