Skip to content

Commit 2b1dbf6

Browse files
LinearEigensolver: default to eps_target = 0 is conceptually wrong (#4634)
the presence of the option, together with the sinvert for the bcs case can lead to confusion Better to be consistent with whatever SLEPc believe is the proper default
1 parent c0986bf commit 2b1dbf6

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

firedrake/eigensolver.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,10 @@ class LinearEigensolver(OptionsManager):
142142
"eps_largest_real": None
143143
"""
144144

145-
DEFAULT_EPS_PARAMETERS = {"eps_type": "krylovschur",
146-
"eps_tol": 1e-10,
147-
"eps_target": 0.0}
145+
DEFAULT_EPS_PARAMETERS = {
146+
"eps_type": "krylovschur",
147+
"eps_tol": 1e-10,
148+
}
148149

149150
def __init__(self, problem, n_evals, *, options_prefix=None,
150151
solver_parameters=None, ncv=None, mpd=None):
@@ -158,8 +159,6 @@ def __init__(self, problem, n_evals, *, options_prefix=None,
158159
for key in self.DEFAULT_EPS_PARAMETERS:
159160
value = self.DEFAULT_EPS_PARAMETERS[key]
160161
solver_parameters.setdefault(key, value)
161-
if self._problem.bcs:
162-
solver_parameters.setdefault("st_type", "sinvert")
163162
super().__init__(solver_parameters, options_prefix)
164163
self.set_from_options(self.es)
165164

tests/firedrake/regression/test_eigensolver.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ def evals(n, degree=1, mesh=None, restrict=False):
2020
bc = DirichletBC(V, 0.0, "on_boundary")
2121
eigenprob = LinearEigenproblem(a, bcs=bc, bc_shift=-6666., restrict=restrict)
2222

23-
# Create corresponding eigensolver, looking for n eigenvalues
24-
eigensolver = LinearEigensolver(
25-
eigenprob, n, solver_parameters={"eps_largest_real": None}
26-
)
23+
# Create corresponding eigensolver, looking for n eigenvalues close to 0
24+
# We use shift-and-invert as spectral transform (SLEPc's default is shift)
25+
solver_parameters = {
26+
"eps_target": 0,
27+
"st_type": "sinvert",
28+
}
29+
eigensolver = LinearEigensolver(eigenprob, n, solver_parameters=solver_parameters)
2730
ncov = eigensolver.solve()
2831

2932
# boffi solns
@@ -67,8 +70,12 @@ def poisson_eigenvalue_2d(i):
6770
ep = LinearEigenproblem(inner(grad(u), grad(v)) * dx,
6871
bcs=bc, bc_shift=666.0)
6972

70-
es = LinearEigensolver(ep, 1, solver_parameters={"eps_gen_hermitian": None,
71-
"eps_largest_real": None})
73+
solver_parameters = {
74+
"eps_gen_hermitian": None,
75+
"eps_target": 0,
76+
"st_type": "sinvert",
77+
}
78+
es = LinearEigensolver(ep, 1, solver_parameters=solver_parameters)
7279

7380
es.solve()
7481
return es.eigenvalue(0)-2.0
@@ -77,7 +84,7 @@ def poisson_eigenvalue_2d(i):
7784
@pytest.mark.skipslepc
7885
def test_evals_2d():
7986
"""2D Eigenvalue convergence test. As with Boffi, we observe that the
80-
convergence rate convergest to 2 from above."""
87+
convergence rate converges to 2 from above."""
8188
errors = np.array([poisson_eigenvalue_2d(i) for i in range(5)])
8289

8390
convergence = np.log(errors[:-1]/errors[1:])/np.log(2.0)

0 commit comments

Comments
 (0)