diff --git a/src/sisl/_ufuncs.py b/src/sisl/_ufuncs.py index cefa3ed0f..929a546f6 100644 --- a/src/sisl/_ufuncs.py +++ b/src/sisl/_ufuncs.py @@ -34,6 +34,12 @@ def decorator(func: FuncType): name = name(func.__name__) old_method = getattr(cls, name, None) + if old_method is not None: + # Check if it is abstract, in which case we can overwrite it + if getattr(old_method, "__isabstractmethod__", False): + # If it is abstract, allow to overwrite it! + old_method = None + if old_method is not None: # Check that the attribute is actually created on the class it-self # This will prohibit warn against functions for derived classes diff --git a/src/sisl/physics/electron.py b/src/sisl/physics/electron.py index 04630a366..bb0db6846 100644 --- a/src/sisl/physics/electron.py +++ b/src/sisl/physics/electron.py @@ -46,7 +46,7 @@ from collections.abc import Callable from functools import reduce -from typing import TYPE_CHECKING, Literal, Optional, Union +from typing import TYPE_CHECKING, Any, Literal, Optional, Union import numpy as np import numpy.typing as npt @@ -108,7 +108,7 @@ __all__ = ["DOS", "PDOS", "COP"] __all__ += ["spin_moment", "spin_contamination"] -__all__ += ["berry_phase", "berry_curvature"] +__all__ += ["berry_phase"] __all__ += ["ahc", "shc", "conductivity"] __all__ += ["wavefunction"] __all__ += ["CoefficientElectron", "StateElectron", "StateCElectron"] @@ -1106,15 +1106,15 @@ def conductivity( @set_module("sisl.physics.electron") def berry_phase( - contour, + contour: BrillouinZone, sub=None, eigvals: bool = False, closed: bool = True, - method="berry", + method: Literal["berry", "zak", "berry:svd", "zak:svd"] = "berry", *, ret_overlap: bool = False, - eigenstate_kwargs=None, - apply_kwargs=None, + eigenstate_kwargs: Optional[dict[str, Any]] = None, + apply_kwargs: Optional[dict[str, Any]] = None, ): r""" Calculate the Berry-phase on a loop path @@ -1138,7 +1138,7 @@ def berry_phase( Parameters ---------- - contour : BrillouinZone + contour : containing the closed contour and has the ``contour.parent`` as an instance of Hamiltonian. The first and last k-point must not be the same. sub : None or list of int, optional @@ -1148,7 +1148,7 @@ def berry_phase( closed : whether or not to include the connection of the last and first points in the loop Forced true for Zak-phase calculations. - method : {"berry", "zak"} + method : "berry" will return the usual integral of the Berry connection over the specified contour "zak" will compute the Zak phase for 1D systems by performing a closed loop integration, see :cite:`Zak1989`. @@ -1159,10 +1159,10 @@ def berry_phase( eigenstate_kwargs : dict, optional keyword arguments passed directly to the ``contour.eigenstate`` method. One should *not* pass ``k`` as that is already used. - eigenstate_kwargs : dict, optional + eigenstate_kwargs : keyword arguments passed directly to the ``contour.eigenstate`` method. One should *not* pass ``k`` as that is already used. - apply_kwargs : dict, optional + apply_kwargs : keyword arguments passed directly to ``contour.apply(**apply_kwargs)``. Notes diff --git a/src/sisl/physics/state.py b/src/sisl/physics/state.py index 4173e8aae..cf768970d 100644 --- a/src/sisl/physics/state.py +++ b/src/sisl/physics/state.py @@ -3,6 +3,7 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. from __future__ import annotations +from abc import abstractmethod from collections.abc import Callable from functools import singledispatchmethod from typing import Literal, Optional @@ -306,6 +307,16 @@ def degenerate(self, atol: float): deg.append(np.append(sidx[idx], sidx[idx[-1] + 1])) return deg + @abstractmethod + def sub(self, *args, **kwargs): + """Return a subset of this instance""" + # defined in _ufuncs_*.py + + @abstractmethod + def remove(self, *args, **kwargs): + """Return a subset of this instance, by removing some elements""" + # defined in _ufuncs_*.py + def __getitem__(self, key): """Return a new coefficient object with only one associated coefficient @@ -404,6 +415,14 @@ def shape(self): """Returns the shape of the state""" return self.state.shape + @abstractmethod + def sub(self, *args, **kwargs): + """Return a subset of this instance""" + + @abstractmethod + def remove(self, *args, **kwargs): + """Return a subset of this instance, by removing some elements""" + def translate(self, isc): r"""Translate the vectors to a new unit-cell position