from dolfin import *
import scipy.sparse as sp
from scipy.sparse.linalg import eigs
mesh = UnitSquareMesh(10,10)
V = FunctionSpace(mesh, "Lagrange", degree = 1)
bc = DirichletBC(V, 0.0, 'on_boundary')
u = TrialFunction(V)
v = TestFunction(V)
a = inner(grad(u), grad(v))*dx
m = u * v * dx
L = inner(Constant(1), v)*dx
A = PETScMatrix()
assemble(a, tensor=A)
bc.apply(A)
M = PETScMatrix()
assemble(m, tensor=M)
# This just converts PETSc to CSR
A = sp.csr_matrix(A.mat().getValuesCSR()[::-1])
M = sp.csr_matrix(M.mat().getValuesCSR()[::-1])
v, V = eigs(A, 6, M, sigma=1.5)
print v
This calculates the physical eigenvalues of your problem. If you want to apply boundary conditions to your mass matrix M you can do a little trick to avoid the 1.0 eigenvalues in your spectrum.
from dolfin import *
import scipy.sparse as sp
import numpy as np
from scipy.sparse.linalg import eigs
mesh = UnitSquareMesh(16,16)
V = FunctionSpace(mesh, "Lagrange", degree = 1)
bc = DirichletBC(V, 0.0, 'on_boundary')
u = TrialFunction(V)
v = TestFunction(V)
a = inner(grad(u), grad(v))*dx
m = u * v * dx
L = inner(Constant(1), v)*dx
A = PETScMatrix()
assemble(a, tensor=A)
bc.apply(A)
M = PETScMatrix()
assemble(m, tensor=M)
# BCs applied this time
bc.apply(M)
# If you had multiple bcs
bcs = [bc]
bcinds = []
for bc in bcs:
bcdict = bc.get_boundary_values()
bcinds.extend(bcdict.keys())
# This just converts PETSc to CSR
A = sp.csr_matrix(A.mat().getValuesCSR()[::-1])
M = sp.csr_matrix(M.mat().getValuesCSR()[::-1])
# Create shift matrix
shift = 1.2345e10*np.ones(len(bcinds))
S = sp.csr_matrix((shift, (bcinds, bcinds)), shape=A.shape)
v, V = eigs(A+S, 6, M, sigma=1.0)
print v
This will shift all your eigenvalues from arising from dirichlet boundary condition application to 1.2345e10. You can vary that value depending on which ones you need.