diff --git a/firedrake/eigensolver.py b/firedrake/eigensolver.py index be768b3049..7248f98437 100644 --- a/firedrake/eigensolver.py +++ b/firedrake/eigensolver.py @@ -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"] @@ -96,7 +102,7 @@ def dm(self): return self.output_space.dm -class LinearEigensolver(OptionsManager): +class LinearEigensolver: r"""Solve a LinearEigenproblem. Parameters @@ -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.""" @@ -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: diff --git a/firedrake/variational_solver.py b/firedrake/variational_solver.py index 4031bf3c5c..708b314e99 100644 --- a/firedrake/variational_solver.py +++ b/firedrake/variational_solver.py @@ -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 @@ -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", @@ -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 @@ -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") @@ -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. @@ -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)