← Back to team overview

dolfin team mailing list archive

Re: Using SLEPcEigenSolver with shift-invert

 

On 03/23/2011 11:55 PM, Neilen Marais wrote:
Hi Marie,

On Wed, Mar 23, 2011 at 6:01 PM, Marie E. Rognes<meg@xxxxxxxxx>  wrote:
On 03/23/2011 04:44 PM, Neilen Marais wrote:

I'm not quite sure if I fully understand what your exact question is,

Just to be clear, the eigen spectrum (using exact math) for a lossless
EM vector wave eqn discretised using Nedelec elements will be real,
and in ascending order

0, 0, 0, 0, ......, mode1_cutoffwavenumber, mode2_cutoffwavenumber, .....

The first zero eigenvalue should be the physical static solution. The
other zero eigenvalues are non-physical, and are artefacts of the
discretisation used. The modeX_cutoffwavenumber values starting from
the smallest is usually what is of practical interest. Numerically the
zero eigenvalues usually show up as ~1e-14 or so.

but using shift-and-invert with a given shift should give you the eigenvalues
closest to that shift. The zero eigenvalues seem to be closer to your given
shift than the others eigenvalues, so the fact that you are getting those is
perhaps not so strange?

Well, for one I'd expect the ARPACK and SLEPc Arnoldi methods to
produce the same results, since the AR in ARPACK stands for Arnoldi :)

Taking your suggestion to heart, I did however play around with other
shifts. If I use a  shift value of 0.03 which is very close the the
smallest non-zero eigenvalue (~0.03056), I still get similar results.
I.e. ARPACK gives only physical eigen values, SLEPc first gives a
number of ~0 eigenvalues.

Upon reading my old code that used ARPACK closely I realised that one
should actually ask for the largest real spectrum (the default for the
scipy ARPACK wrapper). The way I understand shift-invert, this
transforms the original eigenvalues to be 1/(original_eig-sigma) in
the shifted spectrum. This means that the eigen values smaller than
sigma should be negative and therefore shifted far away from "largest
real", while eigen values closest to sigma will have big values in the
shifted spectrum. Alas, doing

esolver.parameters["spectrum"] = "largest real"

results in the largest eigenvalus in the real spectrum, not the
shifted spectrum. This is not what I would like to calculate.

In any case, I would appreciate a recipe for getting the same results
with as ARPACK with a dolfin builtin solver :)


I suggest upgrading to SLEPc 3.1 and use the following:

sigma = 0.03
esolver = dol.SLEPcEigenSolver(S,M)
esolver.parameters["spectrum"] = "target magnitude"
esolver.parameters["solver"] = "arnoldi" # "krylov-schur"
esolver.parameters["spectral_shift"] = sigma
esolver.parameters["spectral_transform"] = "shift-and-invert"
esolver.solve(4)

m = esolver.get_number_converged()
eigs = [esolver.get_eigenvalue(i) for i in range(m)]
print eigs

This gives (using SLEPc 3.1-p5)

[(0.030560806979768325, 0.0), (0.039273074500013092, 0.0), (0.046222796597260411, 0.0), (0.057890000263478195, 0.0)]

Quite a few things changed from SLEPc 3.0 to 3.1, and these were definite improvements in my experience. The use of "target magnitude", was introduced sometime after SLEPc 3.1. (Also note that in my experience, the "krylov-schur" seems faster and more robust than the "arnoldi")

--
Marie




References