Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions firedrake/eigensolver.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
"""Specify and solve finite element eigenproblems."""
import warnings
from functools import cached_property

from petsc4py import PETSc
from petsctools import OptionsManager, flatten_parameters
from ufl import replace, inner, dx

from firedrake.assemble import assemble
from firedrake.bcs import extract_subdomain_ids, restricted_function_space
from firedrake.exceptions import ConvergenceError
from firedrake.function import Function
from firedrake.ufl_expr import TrialFunction, TestFunction
from firedrake.exceptions import ConvergenceError
from ufl import replace, inner, dx
from functools import cached_property

try:
from slepc4py import SLEPc
except ImportError:
SLEPc = None

__all__ = ["LinearEigenproblem",
"LinearEigensolver"]

Expand Down Expand Up @@ -96,7 +102,7 @@ def dm(self):
return self.output_space.dm


class LinearEigensolver(OptionsManager):
class LinearEigensolver:
r"""Solve a LinearEigenproblem.

Parameters
Expand Down Expand Up @@ -159,8 +165,33 @@ def __init__(self, problem, n_evals, *, options_prefix=None,
for key in self.DEFAULT_EPS_PARAMETERS:
value = self.DEFAULT_EPS_PARAMETERS[key]
solver_parameters.setdefault(key, value)
super().__init__(solver_parameters, options_prefix)
self.set_from_options(self.es)

self.options_manager = OptionsManager(solver_parameters, options_prefix)
self.options_manager.set_from_options(self.es)

@property
def parameters(self) -> dict:
return self.options_manager.parameters

@property
def options_prefix(self) -> str:
return self.options_manager.options_prefix

def set_from_options(self, snes: PETSc.SNES) -> None:
warnings.warn(
"'LinearEigensolver.set_from_options' is deprecated, use "
"'LinearEigensolver.options_manager.set_from_options' instead",
FutureWarning
)
self.options_manager.set_from_options(snes)

def inserted_options(self):
warnings.warn(
"'LinearEigensolver.inserted_options' is deprecated, use "
"'LinearEigensolver.options_manager.inserted_options' instead",
FutureWarning
)
return self.options_manager.inserted_options()

def check_es_convergence(self):
r"""Check the convergence of the eigenvalue problem."""
Expand Down Expand Up @@ -193,7 +224,7 @@ def solve(self):

self.es.setDimensions(nev=self.n_evals, ncv=self.ncv, mpd=self.mpd)
self.es.setOperators(self.A_mat, self.M_mat)
with self.inserted_options():
with self.options_manager.inserted_options():
self.es.solve()
nconv = self.es.getConverged()
if nconv == 0:
Expand Down
43 changes: 35 additions & 8 deletions firedrake/variational_solver.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from __future__ import annotations

import ufl
from itertools import chain
import warnings
from contextlib import ExitStack
from itertools import chain
from types import MappingProxyType

import ufl
from petsctools import OptionsManager, flatten_parameters
from ufl import replace, Form

from firedrake import dmhooks, slate, solving, solving_utils, ufl_expr, utils
from firedrake.petsc import PETSc, DEFAULT_KSP_PARAMETERS, DEFAULT_SNES_PARAMETERS
Expand All @@ -14,7 +17,6 @@
from firedrake.ufl_expr import TrialFunction, TestFunction
from firedrake.bcs import DirichletBC, EquationBC, extract_subdomain_ids, restricted_function_space
from firedrake.adjoint_utils import NonlinearVariationalProblemMixin, NonlinearVariationalSolverMixin
from ufl import replace, Form
from functools import cached_property

__all__ = ["LinearVariationalProblem",
Expand Down Expand Up @@ -168,7 +170,7 @@ def compute_bc_lifting(J: ufl.BaseForm | slate.TensorBase,
return F


class NonlinearVariationalSolver(OptionsManager, NonlinearVariationalSolverMixin):
class NonlinearVariationalSolver(NonlinearVariationalSolverMixin):
r"""Solves a :class:`NonlinearVariationalProblem`."""

DEFAULT_SNES_PARAMETERS = DEFAULT_SNES_PARAMETERS
Expand Down Expand Up @@ -275,8 +277,9 @@ def update_diffusivity(current_solution):
problem.J.arguments(),
ksp_defaults=self.DEFAULT_KSP_PARAMETERS,
snes_defaults=self.DEFAULT_SNES_PARAMETERS)
super().__init__(solver_parameters, options_prefix,
default_prefix="firedrake")

self.options_manager = OptionsManager(solver_parameters, options_prefix,
default_prefix="firedrake")
# Now the correct parameters live in self.parameters (via the
# OptionsManager mixin)
mat_type = self.parameters.get("mat_type")
Expand Down Expand Up @@ -322,12 +325,36 @@ def update_diffusivity(current_solution):
# on a subKSP the context is available.
dm = self.snes.getDM()
with dmhooks.add_hooks(dm, self, appctx=self._ctx, save=False):
self.set_from_options(self.snes)
self.options_manager.set_from_options(self.snes)

# Used for custom grid transfer.
self._transfer_operators = ()
self._setup = False

@property
def parameters(self) -> dict:
return self.options_manager.parameters

@property
def options_prefix(self) -> str:
return self.options_manager.options_prefix

def set_from_options(self, snes: PETSc.SNES) -> None:
warnings.warn(
"'NonlinearVariationalSolver.set_from_options' is deprecated, use "
"'NonlinearVariationalSolver.options_manager.set_from_options' instead",
FutureWarning
)
self.options_manager.set_from_options(snes)

def inserted_options(self):
warnings.warn(
"'NonlinearVariationalSolver.inserted_options' is deprecated, use "
"'NonlinearVariationalSolver.options_manager.inserted_options' instead",
FutureWarning
)
return self.options_manager.inserted_options()

def set_transfer_manager(self, manager):
r"""Set the object that manages transfer between grid levels.
Typically a :class:`~.TransferManager` object.
Expand Down Expand Up @@ -391,7 +418,7 @@ def solve(self, bounds=None):
with ExitStack() as stack:
# Ensure options database has full set of options (so monitors
# work right)
for ctx in chain([self.inserted_options()],
for ctx in chain([self.options_manager.inserted_options()],
[dmhooks.add_hooks(dm, self, appctx=self._ctx) for dm in problem_dms],
self._transfer_operators):
stack.enter_context(ctx)
Expand Down
Loading