class KpointTest(unittest.TestCase): def setUp(self): self.lattice = Lattice.cubic(10.0) self.kpoint = Kpoint([0.1, 0.4, -0.5], self.lattice, label="X") def test_properties(self): self.assertEqual(self.kpoint.frac_coords[0], 0.1) self.assertEqual(self.kpoint.frac_coords[1], 0.4) self.assertEqual(self.kpoint.frac_coords[2], -0.5) self.assertEqual(self.kpoint.a, 0.1) self.assertEqual(self.kpoint.b, 0.4) self.assertEqual(self.kpoint.c, -0.5) self.assertEqual(self.lattice, Lattice.cubic(10.0)) self.assertEqual(self.kpoint.cart_coords[0], 1.0) self.assertEqual(self.kpoint.cart_coords[1], 4.0) self.assertEqual(self.kpoint.cart_coords[2], -5.0) self.assertEqual(self.kpoint.label, "X") def test_as_dict(self): self.assertIsInstance(self.kpoint.as_dict()["fcoords"], list) self.assertIsInstance(self.kpoint.as_dict()["ccoords"], list) self.assertNotIsInstance(self.kpoint.as_dict()["fcoords"][0], numpy.float64) self.assertNotIsInstance(self.kpoint.as_dict()["ccoords"][0], numpy.float64) self.assertListEqual(self.kpoint.as_dict()["fcoords"], [0.1, 0.4, -0.5]) self.assertListEqual(self.kpoint.as_dict()["ccoords"], [1.0, 4.0, -5.0])
def get_band_structure(self): """Return a BandStructureSymmLine object interpolating bands along a High symmetry path calculated from the structure using HighSymmKpath function""" kpath = HighSymmKpath(self.data.structure) kpt_line = [ Kpoint(k, self.data.structure.lattice) for k in kpath.get_kpoints(coords_are_cartesian=False)[0] ] kpoints = np.array([kp.frac_coords for kp in kpt_line]) labels_dict = { l: k for k, l in zip(*kpath.get_kpoints(coords_are_cartesian=False)) if l } lattvec = self.data.get_lattvec() egrid, vgrid = fite.getBands(kpoints, self.equivalences, lattvec, self.coeffs) bands_dict = {Spin.up: (egrid / units.eV)} sbs = BandStructureSymmLine( kpoints, bands_dict, self.data.structure.lattice.reciprocal_lattice, self.efermi / units.eV, labels_dict=labels_dict) return sbs
def test_from_dict(self): d = self.kpoint.as_dict() kpoint = Kpoint.from_dict(d) self.assertEqual(kpoint.frac_coords[0], 0.1) self.assertEqual(kpoint.frac_coords[1], 0.4) self.assertEqual(kpoint.frac_coords[2], -0.5) self.assertEqual(kpoint.a, 0.1) self.assertEqual(kpoint.b, 0.4) self.assertEqual(kpoint.c, -0.5) self.assertEqual(kpoint.lattice, Lattice.cubic(10.0)) self.assertEqual(kpoint.cart_coords[0], 1.0) self.assertEqual(kpoint.cart_coords[1], 4.0) self.assertEqual(kpoint.cart_coords[2], -5.0) self.assertEqual(kpoint.label, "X")
def __init__(self, qpoints, frequencies, lattice, nac_frequencies=None, eigendisplacements=None, nac_eigendisplacements=None, labels_dict=None, coords_are_cartesian=False, structure=None): """ Args: qpoints: list of qpoint as numpy arrays, in frac_coords of the given lattice by default frequencies: list of phonon frequencies in THz as a numpy array with shape (3*len(structure), len(qpoints)). The First index of the array refers to the band and the second to the index of the qpoint. lattice: The reciprocal lattice as a pymatgen Lattice object. Pymatgen uses the physics convention of reciprocal lattice vectors WITH a 2*pi coefficient. nac_frequencies: Frequencies with non-analytical contributions at Gamma in THz. A list of tuples. The first element of each tuple should be a list defining the direction (not necessarily a versor, will be normalized internally). The second element containing the 3*len(structure) phonon frequencies with non-analytical correction for that direction. eigendisplacements: the phonon eigendisplacements associated to the frequencies in cartesian coordinates. A numpy array of complex numbers with shape (3*len(structure), len(qpoints), len(structure), 3). he First index of the array refers to the band, the second to the index of the qpoint, the third to the atom in the structure and the fourth to the cartesian coordinates. nac_eigendisplacements: the phonon eigendisplacements associated to the non-analytical frequencies in nac_frequencies in cartesian coordinates. A list of tuples. The first element of each tuple should be a list defining the direction. The second element containing a numpy array of complex numbers with shape (3*len(structure), len(structure), 3). labels_dict: (dict) of {} this links a qpoint (in frac coords or cartesian coordinates depending on the coords) to a label. coords_are_cartesian: Whether the qpoint coordinates are cartesian. structure: The crystal structure (as a pymatgen Structure object) associated with the band structure. This is needed if we provide projections to the band structure """ self.lattice_rec = lattice self.qpoints = [] self.labels_dict = {} self.structure = structure if eigendisplacements is None: eigendisplacements = np.array([]) self.eigendisplacements = eigendisplacements if labels_dict is None: labels_dict = {} for q in qpoints: # let see if this qpoint has been assigned a label label = None for c in labels_dict: if np.linalg.norm(q - np.array(labels_dict[c])) < 0.0001: label = c self.labels_dict[label] = Kpoint( q, lattice, label=label, coords_are_cartesian=coords_are_cartesian) self.qpoints.append( Kpoint(q, lattice, label=label, coords_are_cartesian=coords_are_cartesian)) self.bands = frequencies self.nb_bands = len(self.bands) self.nb_qpoints = len(self.qpoints) # normalize directions for nac_frequencies and nac_eigendisplacements self.nac_frequencies = [] self.nac_eigendisplacements = [] if nac_frequencies is not None: for t in nac_frequencies: self.nac_frequencies.append( ([i / np.linalg.norm(t[0]) for i in t[0]], t[1])) if nac_eigendisplacements is not None: for t in nac_eigendisplacements: self.nac_eigendisplacements.append( ([i / np.linalg.norm(t[0]) for i in t[0]], t[1]))
def setUp(self): self.lattice = Lattice.cubic(10.0) self.kpoint = Kpoint([0.1, 0.4, -0.5], self.lattice, label="X")