from typing import Union, Optional
import numpy as np
from .mu_kernels import BerryKernel
from .models import Kmodel
from .operators import KspaceOpera
from .responses import Kubo
__all__ = ["BerryCurvature", "QuantumMetric", "QuantumGeometricTensor"]
[docs]
class BerryCurvature(Kubo):
r"""Computes the k-space Berry curvature
(oriented along a direction perpendicular to `alpha` and `beta`)
for a single band.
Attributes:
model: An instance of :class:`~py4mulas.models.Kmodel`
alpha: An instance of :class:`~py4mulas.operators.KspaceOpera`, a longitudinal in-plane direction
beta: An instance of :class:`~py4mulas.operators.KspaceOpera`, a transversal in-plane direction
Note:
For spin or orbital berry curvature `alpha` or `beta` should be either a spin or orbital operator.
"""
def __init__(
self,
model: Kmodel,
alpha: Union[str, KspaceOpera] = "x",
beta: Union[str, KspaceOpera] = "y",
):
super().__init__(
model, alpha=alpha, beta=beta, mu_kernel=BerryKernel(), kspace_options=None
)
[docs]
def __call__(self, band: Optional[int] = None) -> np.ndarray:
result = super().__call__(k_resolved=True)
if band is not None:
_check_band(band, norbs=self.norbs)
return result[:, band]
return result
[docs]
class QuantumMetric(BerryCurvature):
def __init__(self,
model: Kmodel,
alpha: Union[str, KspaceOpera] = "x",
beta: Union[str, KspaceOpera] = "y",
):
super().__init__(model, alpha=alpha, beta=beta)
[docs]
def __call__(self, band: int = 0) -> np.ndarray:
return 0.5 * super().__call__(band).imag
[docs]
class QuantumGeometricTensor(BerryCurvature):
def __init__(self,
model: Kmodel,
alpha: Union[str, KspaceOpera] = "x",
beta: Union[str, KspaceOpera] = "y",
):
super().__init__(model, alpha=alpha, beta=beta)
[docs]
def __call__(self, band: int = 0) -> np.ndarray:
return - 0.5 * super().__call__(band)
def _check_band(band=0, norbs=2):
assert isinstance(band, int)
assert 0 <= band < norbs