Skip to content

Commit

Permalink
plum is only able to correctly dispatch on keyword arguments if they …
Browse files Browse the repository at this point in the history
…have a default value. Make the number of modes and the tolerance optional in POD functions
  • Loading branch information
francesco-ballarin committed Aug 29, 2023
1 parent 57658ea commit 9a6fd71
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 29 deletions.
25 changes: 17 additions & 8 deletions rbnicsx/_backends/proper_orthogonal_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
from rbnicsx._cpp import cpp_library


real_zero = petsc4py.PETSc.RealType(0.0)


def proper_orthogonal_decomposition_functions( # type: ignore[no-any-unimported]
functions_list: FunctionsList[Function],
compute_inner_product: typing.Callable[[Function], typing.Callable[[Function], petsc4py.PETSc.RealType]],
scale: typing.Callable[[Function, petsc4py.PETSc.RealType], None],
N: int, tol: petsc4py.PETSc.RealType, normalize: bool = True
N: int = -1, tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], FunctionsList[Function], typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -39,9 +42,9 @@ def proper_orthogonal_decomposition_functions( # type: ignore[no-any-unimported
scale
A callable with signature scale(function, factor) to scale any function by a given factor.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand All @@ -67,8 +70,8 @@ def proper_orthogonal_decomposition_functions_block( # type: ignore[no-any-unim
compute_inner_products: typing.Sequence[
typing.Callable[[Function], typing.Callable[[Function], petsc4py.PETSc.RealType]]],
scale: typing.Callable[[Function, petsc4py.PETSc.RealType], None],
N: typing.Union[int, typing.List[int]],
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]],
N: typing.Union[int, typing.List[int]] = -1,
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]] = real_zero,
normalize: bool = True
) -> typing.Tuple[
typing.List[np.typing.NDArray[petsc4py.PETSc.RealType]], typing.List[FunctionsList[Function]],
Expand All @@ -92,9 +95,11 @@ def proper_orthogonal_decomposition_functions_block( # type: ignore[no-any-unim
N
Maximum number of modes to be computed. If an integer value is passed then the same maximum number is
used for each block. To set a different maximum number of modes for each block pass a list of integers.
If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy. If a floating point value is passed then the same tolerance is
used for each block. To set a different tolerance for each block pass a list of floating point numbers.
If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand Down Expand Up @@ -132,7 +137,7 @@ def proper_orthogonal_decomposition_functions_block( # type: ignore[no-any-unim


def proper_orthogonal_decomposition_tensors( # type: ignore[no-any-unimported]
tensors_list: TensorsList, N: int, tol: petsc4py.PETSc.RealType, normalize: bool = True
tensors_list: TensorsList, N: int = -1, tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], TensorsList, typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -144,9 +149,9 @@ def proper_orthogonal_decomposition_tensors( # type: ignore[no-any-unimported]
tensors_list
Collected tensors.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected tensors.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand Down Expand Up @@ -243,6 +248,10 @@ def _solve_eigenvalue_problem( # type: ignore[no-any-unimported]
3. Eigenvectors of the correlation matrix. Only the first few eigenvectors are returned, till
either the maximum number N is reached or the tolerance on the retained energy is fulfilled.
"""
assert N > 0 or N == -1
if N == -1:
N = len(snapshots)

correlation_matrix = create_online_matrix(len(snapshots), len(snapshots))
for (j, snapshot_j) in enumerate(snapshots):
compute_inner_product_partial_j = compute_inner_product(snapshot_j)
Expand Down
21 changes: 12 additions & 9 deletions rbnicsx/backends/proper_orthogonal_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
from rbnicsx._backends.proper_orthogonal_decomposition import (
proper_orthogonal_decomposition_functions as proper_orthogonal_decomposition_functions_super,
proper_orthogonal_decomposition_functions_block as proper_orthogonal_decomposition_functions_block_super,
proper_orthogonal_decomposition_tensors as proper_orthogonal_decomposition_tensors_super)
proper_orthogonal_decomposition_tensors as proper_orthogonal_decomposition_tensors_super,
real_zero)
from rbnicsx.backends.functions_list import FunctionsList
from rbnicsx.backends.tensors_list import TensorsList

Expand All @@ -30,7 +31,7 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported]
functions_list: FunctionsList,
compute_inner_product: typing.Callable[
[dolfinx.fem.Function], typing.Callable[[dolfinx.fem.Function], petsc4py.PETSc.RealType]],
N: int, tol: petsc4py.PETSc.RealType, normalize: bool = True
N: int = -1, tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], FunctionsList, typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -46,9 +47,9 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported]
The resulting modes will be orthonormal w.r.t. this inner product.
Use rbnicsx.backends.bilinear_form_action to generate the callable x from a UFL form.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand All @@ -68,7 +69,7 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported]

@plum.overload
def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa: F811
tensors_list: TensorsList, N: int, tol: petsc4py.PETSc.RealType, normalize: bool = True
tensors_list: TensorsList, N: int = -1, tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], TensorsList, typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -80,9 +81,9 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa:
tensors_list
Collected tensors.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected tensors.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand All @@ -109,8 +110,8 @@ def proper_orthogonal_decomposition_block( # type: ignore[no-any-unimported]
functions_lists: typing.Sequence[FunctionsList],
compute_inner_products: typing.Sequence[
typing.Callable[[dolfinx.fem.Function], typing.Callable[[dolfinx.fem.Function], petsc4py.PETSc.RealType]]],
N: typing.Union[int, typing.List[int]],
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]],
N: typing.Union[int, typing.List[int]] = -1,
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]] = real_zero,
normalize: bool = True
) -> typing.Tuple[
typing.List[np.typing.NDArray[petsc4py.PETSc.RealType]], typing.List[FunctionsList],
Expand All @@ -133,9 +134,11 @@ def proper_orthogonal_decomposition_block( # type: ignore[no-any-unimported]
N
Maximum number of modes to be computed. If an integer value is passed then the same maximum number is
used for each block. To set a different maximum number of modes for each block pass a list of integers.
If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy. If a floating point value is passed then the same tolerance is
used for each block. To set a different tolerance for each block pass a list of floating point numbers.
If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand Down
23 changes: 13 additions & 10 deletions rbnicsx/online/proper_orthogonal_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
from rbnicsx._backends.proper_orthogonal_decomposition import (
proper_orthogonal_decomposition_functions as proper_orthogonal_decomposition_functions_super,
proper_orthogonal_decomposition_functions_block as proper_orthogonal_decomposition_functions_block_super,
proper_orthogonal_decomposition_tensors as proper_orthogonal_decomposition_tensors_super)
proper_orthogonal_decomposition_tensors as proper_orthogonal_decomposition_tensors_super,
real_zero)
from rbnicsx.online.functions_list import FunctionsList
from rbnicsx.online.projection import matrix_action
from rbnicsx.online.tensors_list import TensorsList
Expand All @@ -27,8 +28,8 @@

@plum.overload
def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa: F811
functions_list: FunctionsList, inner_product: petsc4py.PETSc.Mat, N: int, tol: petsc4py.PETSc.RealType,
normalize: bool = True
functions_list: FunctionsList, inner_product: petsc4py.PETSc.Mat, N: int = -1,
tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], FunctionsList, typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -43,9 +44,9 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa:
Online matrix which defines the inner product. The resulting modes will be orthonormal
w.r.t. this inner product.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize : bool, optional
If true (default), the modes are scaled to unit norm.
Expand All @@ -67,7 +68,7 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa:

@plum.overload
def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa: F811
tensors_list: TensorsList, N: int, tol: petsc4py.PETSc.RealType, normalize: bool = True
tensors_list: TensorsList, N: int = -1, tol: petsc4py.PETSc.RealType = real_zero, normalize: bool = True
) -> typing.Tuple[
np.typing.NDArray[petsc4py.PETSc.RealType], TensorsList, typing.List[petsc4py.PETSc.Vec]
]:
Expand All @@ -79,9 +80,9 @@ def proper_orthogonal_decomposition( # type: ignore[no-any-unimported] # noqa:
tensors_list
Collected tensors.
N
Maximum number of modes to be computed.
Maximum number of modes to be computed. If not provided, it will be set to the number of collected tensors.
tol
Tolerance on the retained energy.
Tolerance on the retained energy. If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand All @@ -106,8 +107,8 @@ def proper_orthogonal_decomposition(*args, **kwargs): # type: ignore[no-untyped

def proper_orthogonal_decomposition_block( # type: ignore[no-any-unimported]
functions_lists: typing.Sequence[FunctionsList], inner_products: typing.List[petsc4py.PETSc.Mat],
N: typing.Union[int, typing.List[int]],
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]],
N: typing.Union[int, typing.List[int]] = -1,
tol: typing.Union[petsc4py.PETSc.RealType, typing.List[petsc4py.PETSc.RealType]] = real_zero,
normalize: bool = True
) -> typing.Tuple[
typing.List[np.typing.NDArray[petsc4py.PETSc.RealType]], typing.List[FunctionsList],
Expand All @@ -128,9 +129,11 @@ def proper_orthogonal_decomposition_block( # type: ignore[no-any-unimported]
N
Maximum number of modes to be computed. If an integer value is passed then the same maximum number is
used for each block. To set a different maximum number of modes for each block pass a list of integers.
If not provided, it will be set to the number of collected snapshots.
tol
Tolerance on the retained energy. If a floating point value is passed then the same tolerance is
used for each block. To set a different tolerance for each block pass a list of floating point numbers.
If not provided, it will be set to zero.
normalize
If true (default), the modes are scaled to unit norm.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import mpi4py.MPI
import numpy as np
import petsc4py.PETSc
import plum
import pytest
import ufl

Expand Down Expand Up @@ -210,5 +211,6 @@ def test_backends_proper_orthogonal_decomposition_zero( # type: ignore[no-any-u

def test_backends_proper_orthogonal_decomposition_wrong_iterable() -> None:
"""Check rbnicsx.backends.proper_orthogonal_decomposition raises when providing a plain list."""
with pytest.raises(RuntimeError):
with pytest.raises(plum.NotFoundLookupError) as excinfo:
rbnicsx.backends.proper_orthogonal_decomposition(list(), N=0, tol=0.0) # type: ignore[call-overload]
assert str(excinfo.value) == "For function `proper_orthogonal_decomposition`, `([],)` could not be resolved."
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import _pytest.fixtures
import numpy as np
import petsc4py.PETSc
import plum
import pytest

import rbnicsx.online
Expand Down Expand Up @@ -281,5 +282,6 @@ def test_online_proper_orthogonal_decomposition_zero( # type: ignore[no-any-uni

def test_online_proper_orthogonal_decomposition_wrong_iterable() -> None:
"""Check rbnicsx.online.proper_orthogonal_decomposition raises when providing a plain list."""
with pytest.raises(RuntimeError):
with pytest.raises(plum.NotFoundLookupError) as excinfo:
rbnicsx.online.proper_orthogonal_decomposition(list(), N=0, tol=0.0) # type: ignore[call-overload]
assert str(excinfo.value) == "For function `proper_orthogonal_decomposition`, `([],)` could not be resolved."

0 comments on commit 9a6fd71

Please sign in to comment.