Source code for dynasor.modes.band

from __future__ import annotations
from typing import TYPE_CHECKING
from numpy.typing import NDArray
from ..units import radians_per_fs_to_THz
from .tools import make_table
from .complex_coordinate import Q, P, F

if TYPE_CHECKING:
    from .qpoint import QPoint
    from .mode_projector import ModeProjector


[docs] class Band: """Represents properties of a single band belonging to a q-point. To modify the coordinates `Q`, `P` and `F` use `band.Q` and see doc for :class:`~dynasor.modes.complex_coordinate.ComplexCoordinate`. Parameters ---------- q_index q-point index. band_index Band index. mp Mode projector. """ def __init__(self, q_index: int, band_index: int, mp: ModeProjector): self._q = q_index self._s = band_index self._mp = mp def __repr__(self): return str(self) def __str__(self): s = ['### Band ###'] s += [f'Band index: {self.index}'] s += [f'q-point: [{self.qpoint.index}] {self.qpoint.q_reduced}'] s += [f'Frequency: {self.omega * radians_per_fs_to_THz:.2f} THz'] s += ['Polarization:'] string = '\n'.join(s) string += make_table(self.polarization) string += f""" {'Q':<20}{'P':<20}{'F':<20} Value: {self.Q.complex:<20.2f}{self.P.complex:<20.2f}{self.F.complex:<20.2f} Amplitude: {self.Q.amplitude:<20.2f}{self.P.amplitude:<20.2f}{self.F.amplitude:<20.2f} Phase: {self.Q.phase:<20.2f}{self.P.phase:<20.2f}{self.F.phase:<20.2f} Energy: {self.potential_energy:<20.2f}{self.kinetic_energy:<20.2f}{self.virial_energy:<20.2f} """ return string @property def index(self) -> int: """The index of the band at the q-point.""" return self._s @property def qpoint(self) -> 'QPoint': """The q-point to which the band belongs.""" return self._mp[self._q] @property def omega(self) -> float: """Slice, see doc for :class:`ModeProjector`.""" return self.qpoint.omegas[self.index] @property def polarization(self) -> NDArray[float]: """Slice, see doc for :class:`ModeProjector`.""" return self.qpoint.polarizations[self.index] @property def eigenmode(self) -> NDArray[float]: """Slice, see doc for :class:`ModeProjector`.""" return self.qpoint.eigenmodes[self.index] @property def potential_energy(self) -> float: """Slice, see doc for :class:`ModeProjector`.""" return self.qpoint.potential_energies[self.index] @property def kinetic_energy(self) -> float: """Slice, see doc for :class:`ModeProjector`.""" return self.qpoint.kinetic_energies[self.index] @property def virial_energy(self) -> float: """Slice, see doc for :class:`ModeProjector`""" return self.qpoint.virial_energies[self.index] @property def Q(self) -> float: """The mode coordinate.""" return Q(self.qpoint.index, self.index, self._mp) @property def P(self) -> float: """The mode momentum.""" return P(self.qpoint.index, self.index, self._mp) @property def F(self) -> NDArray[float]: """The mode force""" return F(self.qpoint.index, self.index, self._mp)