Beispiel #1
0
    def __init__(self, atoms=None, calc=None, filename=None):
        """Band-structure object.

        Create a band-structure object from an Atoms object, a calculator or
        from a pickle file.  Labels for special points will be automatically
        added.
        """
        if filename:
            self.read(filename)
        else:
            atoms = atoms or calc.atoms
            calc = calc or atoms.calc

            self.cell = atoms.cell
            self.kpts = calc.get_ibz_k_points()
            self.fermilevel = calc.get_fermi_level()

            energies = []
            for s in range(calc.get_number_of_spins()):
                energies.append([calc.get_eigenvalues(kpt=k, spin=s)
                                 for k in range(len(self.kpts))])
            self.energies = np.array(energies)

            x, X, labels = labels_from_kpts(self.kpts, self.cell)
            self.xcoords = x
            self.label_xcoords = X
            self.labels = labels
Beispiel #2
0
def atoms2bandpath(atoms,
                   path='default',
                   k_points=False,
                   ibz_k_points=False,
                   dimension=3,
                   verbose=False):
    cell = atoms.get_cell()
    icell = atoms.get_reciprocal_cell()

    try:
        cs = crystal_structure_from_cell(cell)
    except ValueError:
        cs = None

    if verbose:
        if cs:
            print('Crystal:', cs)
            print('Special points:', special_paths[cs])
        print('Lattice vectors:')
        for i, v in enumerate(cell):
            print('{}: ({:16.9f},{:16.9f},{:16.9f})'.format(i + 1, *v))
        print('Reciprocal vectors:')
        for i, v in enumerate(icell):
            print('{}: ({:16.9f},{:16.9f},{:16.9f})'.format(i + 1, *v))

    # band path
    special_points = None
    if path:
        if path == 'default':
            path = special_paths[cs]
        paths = []
        special_points = get_special_points(cell)
        for names in parse_path_string(path):
            points = []
            for name in names:
                points.append(np.dot(icell.T, special_points[name]))
            paths.append((names, points))
    else:
        paths = None

    # k points
    points = None
    if atoms.calc is not None and hasattr(atoms.calc, 'get_bz_k_points'):
        bzk = atoms.calc.get_bz_k_points()
        if path is None:
            try:
                size, offset = get_monkhorst_pack_size_and_offset(bzk)
            except ValueError:
                # This was not a MP-grid.  Must be a path in the BZ:
                path = ''.join(labels_from_kpts(bzk, cell)[2])

        if k_points:
            points = bzk
        elif ibz_k_points:
            points = atoms.calc.get_ibz_k_points()

    return BandPath(cell, kpts=points, special_points=special_points)
Beispiel #3
0
def get_band_structure(atoms=None, calc=None, _bandpath=None, _reference=None):
    """Create band structure object from Atoms or calculator."""
    # _bandpath and _reference are used internally at the moment, but
    # the exact implementation will probably change.  WIP.
    #
    # XXX We throw away info about the bandpath when we create the calculator.
    # If we have kept the bandpath, we can provide it as an argument here.
    # It would be wise to check that the bandpath kpoints are the same as
    # those stored in the calculator.
    atoms = atoms if atoms is not None else calc.atoms
    calc = calc if calc is not None else atoms.calc

    kpts = calc.get_ibz_k_points()

    energies = []
    for s in range(calc.get_number_of_spins()):
        energies.append(
            [calc.get_eigenvalues(kpt=k, spin=s) for k in range(len(kpts))])
    energies = np.array(energies)

    if _bandpath is None:
        from ase.dft.kpoints import BandPath, get_cellinfo, labels_from_kpts
        cellinfo = get_cellinfo(cell=atoms.cell)
        special_points = cellinfo.special_points
        _, _, labels = labels_from_kpts(kpts,
                                        cell=atoms.cell,
                                        special_points=special_points)
        _bandpath = BandPath(labelseq=labels,
                             cell=atoms.cell,
                             scaled_kpts=kpts,
                             special_points=special_points)

    if _reference is None:
        # Fermi level should come from the GS calculation, not the BS one!
        _reference = calc.get_fermi_level()

    return BandStructure(path=_bandpath,
                         energies=energies,
                         reference=_reference)
Beispiel #4
0
 def get_labels(self):
     return labels_from_kpts(self.kpts, self.cell)
Beispiel #5
0
def plot_reciprocal_cell(atoms,
                         path='default',
                         k_points=False,
                         ibz_k_points=False,
                         plot_vectors=True,
                         dimension=3,
                         output=None,
                         verbose=False):
    import matplotlib.pyplot as plt

    cell = atoms.get_cell()
    icell = atoms.get_reciprocal_cell()

    try:
        cs = crystal_structure_from_cell(cell)
    except ValueError:
        cs = None

    if verbose:
        if cs:
            print('Crystal:', cs)
            print('Special points:', special_paths[cs])
        print('Lattice vectors:')
        for i, v in enumerate(cell):
            print('{}: ({:16.9f},{:16.9f},{:16.9f})'.format(i + 1, *v))
        print('Reciprocal vectors:')
        for i, v in enumerate(icell):
            print('{}: ({:16.9f},{:16.9f},{:16.9f})'.format(i + 1, *v))

    # band path
    if path:
        if path == 'default':
            path = special_paths[cs]
        paths = []
        special_points = get_special_points(cell)
        for names in parse_path_string(path):
            points = []
            for name in names:
                points.append(np.dot(icell.T, special_points[name]))
            paths.append((names, points))
    else:
        paths = None

    # k points
    points = None
    if atoms.calc is not None and hasattr(atoms.calc, 'get_bz_k_points'):
        bzk = atoms.calc.get_bz_k_points()
        if path is None:
            try:
                size, offset = get_monkhorst_pack_size_and_offset(bzk)
            except ValueError:
                # This was not a MP-grid.  Must be a path in the BZ:
                path = ''.join(labels_from_kpts(bzk, cell)[2])

        if k_points:
            points = bzk
        elif ibz_k_points:
            points = atoms.calc.get_ibz_k_points()
        if points is not None:
            for i in range(len(points)):
                points[i] = np.dot(icell.T, points[i])

    kwargs = {
        'cell': cell,
        'vectors': plot_vectors,
        'paths': paths,
        'points': points
    }

    if dimension == 1:
        bz1d_plot(**kwargs)
    elif dimension == 2:
        bz2d_plot(**kwargs)
    else:
        bz3d_plot(interactive=True, **kwargs)

    if output:
        plt.savefig(output)
    else:
        plt.show()
Beispiel #6
0
 def get_labels(self):
     return labels_from_kpts(self.path.scaled_kpts,
                             self.path.cell,
                             special_points=self.path.special_points)
 def get_labels(self):
     return labels_from_kpts(self.kpts, self.cell)