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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from petsctools import OptionsManager, flatten_parameters
import petsctools

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)
Comment on lines +169 to +170

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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


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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return self.options_manager.parameters
return petsctools.get_options(self.es).parameters


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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return self.options_manager.options_prefix
return petsctools.get_options(self.es).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)
Comment on lines +180 to +186

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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 set_from_options(self, snes: PETSc.SNES) -> None:
warnings.warn(
"'LinearEigensolver.set_from_options' is deprecated, "
"'the ES has already been set from options.",
FutureWarning
)


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()
Comment on lines +188 to +194

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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 inserted_options(self):
warnings.warn(
"'LinearEigensolver.inserted_options' is deprecated, use "
"'petsctools.inserted_options(LinearEigensolver.es)' instead",
FutureWarning
)
return petsctools.inserted_options(self.es)


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():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with self.options_manager.inserted_options():
with petsctools.inserted_options(self.es):

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