Coverage for local_installation/dynasor/modes/band.py: 62%

50 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-15 07:34 +0000

1from __future__ import annotations 

2from typing import TYPE_CHECKING 

3from ..units import radians_per_fs_to_THz 

4from .tools import make_table 

5from .complex_coordinate import Q, P, F 

6 

7if TYPE_CHECKING: 7 ↛ 8line 7 didn't jump to line 8 because the condition on line 7 was never true

8 from .qpoint import QPoint 

9 

10 

11class Band: 

12 """Represents properties of a single band belonging to a q-point 

13 

14 To modify the coordinates `Q`, `P` and `F` use `band.Q` and see doc for 

15 :class:`dynasor.modes.complex_coordinate.ComplexCoordinate` 

16 """ 

17 def __init__(self, q_index, band_index, mp): 

18 self._q = q_index 

19 self._s = band_index 

20 self._mp = mp 

21 

22 def __repr__(self): 

23 return str(self) 

24 

25 def __str__(self): 

26 string = f"""### Band ### 

27Band index: {self.index} 

28q-point: [{self.qpoint.index}] {self.qpoint.q_reduced} 

29Frequency: {self.omega * radians_per_fs_to_THz:.2f} THz 

30Polarization: 

31""" 

32 string += make_table(self.polarization) 

33 string += f""" 

34 {'Q':<20}{'P':<20}{'F':<20} 

35Value: {self.Q.complex:<20.2f}{self.P.complex:<20.2f}{self.F.complex:<20.2f} 

36Amplitude: {self.Q.amplitude:<20.2f}{self.P.amplitude:<20.2f}{self.F.amplitude:<20.2f} 

37Phase: {self.Q.phase:<20.2f}{self.P.phase:<20.2f}{self.F.phase:<20.2f} 

38Energy: {self.potential_energy:<20.2f}{self.kinetic_energy:<20.2f}{self.virial_energy:<20.2f} 

39""" 

40 return string 

41 

42 @property 

43 def index(self): 

44 """The index of the band at the q-point""" 

45 return self._s 

46 

47 @property 

48 def qpoint(self) -> 'QPoint': 

49 """The q-point to which the band belongs""" 

50 return self._mp[self._q] 

51 

52 @property 

53 def omega(self): 

54 """Slice, see doc for ModeProjector""" 

55 return self.qpoint.omegas[self.index] 

56 

57 @property 

58 def polarization(self): 

59 """Slice, see doc for ModeProjector""" 

60 return self.qpoint.polarizations[self.index] 

61 

62 @property 

63 def eigenmode(self): 

64 """Slice, see doc for ModeProjector""" 

65 return self.qpoint.eigenmodes[self.index] 

66 

67 @property 

68 def potential_energy(self): 

69 """Slice, see doc for ModeProjector""" 

70 return self.qpoint.potential_energies[self.index] 

71 

72 @property 

73 def kinetic_energy(self): 

74 """Slice, see doc for ModeProjector""" 

75 return self.qpoint.kinetic_energies[self.index] 

76 

77 @property 

78 def virial_energy(self): 

79 """Slice, see doc for ModeProjector""" 

80 return self.qpoint.virial_energies[self.index] 

81 

82 @property 

83 def Q(self) -> Q: 

84 """The mode coordinate""" 

85 return Q(self.qpoint.index, self.index, self._mp) 

86 

87 @property 

88 def P(self) -> P: 

89 """The mode momentum""" 

90 return P(self.qpoint.index, self.index, self._mp) 

91 

92 @property 

93 def F(self) -> F: 

94 """The mode force""" 

95 return F(self.qpoint.index, self.index, self._mp)