Example #1
0
def atoms2bandstructure(atoms, parser, args):
    cell = atoms.get_cell()
    calc = atoms.calc
    bzkpts = calc.get_bz_k_points()
    ibzkpts = calc.get_ibz_k_points()
    efermi = calc.get_fermi_level()
    nibz = len(ibzkpts)
    nspins = 1 + int(calc.get_spin_polarized())

    eps = np.array([[calc.get_eigenvalues(kpt=k, spin=s)
                     for k in range(nibz)]
                    for s in range(nspins)])
    if not args.quiet:
        print('Spins, k-points, bands: {}, {}, {}'.format(*eps.shape))

    if bzkpts is None:
        if ibzkpts is None:
            raise ValueError('Cannot find any k-point data')
        else:
            path_kpts = ibzkpts
    else:
        try:
            size, offset = get_monkhorst_pack_size_and_offset(bzkpts)
        except ValueError:
            path_kpts = ibzkpts
        else:
            if not args.quiet:
                print('Interpolating from Monkhorst-Pack grid (size, offset):')
                print(size, offset)
            if args.path is None:
                err = 'Please specify a path!'
                try:
                    cs = crystal_structure_from_cell(cell)
                except ValueError:
                    err += ('\nASE cannot automatically '
                            'recognize this crystal structure')
                else:
                    from ase.dft.kpoints import special_paths
                    kptpath = special_paths[cs]
                    err += ('\nIt looks like you have a {} crystal structure.'
                            '\nMaybe you want its special path:'
                            ' {}'.format(cs, kptpath))
                parser.error(err)
            bz2ibz = calc.get_bz_to_ibz_map()

            path_kpts = bandpath(args.path, atoms.cell, args.points).kpts

            icell = atoms.get_reciprocal_cell()
            eps = monkhorst_pack_interpolate(path_kpts, eps.transpose(1, 0, 2),
                                             icell, bz2ibz, size, offset)
            eps = eps.transpose(1, 0, 2)

    special_points = get_special_points(cell)
    path = BandPath(atoms.cell, kpts=path_kpts,
                    special_points=special_points)

    return BandStructure(path, eps, reference=efermi)
Example #2
0
def labels_from_kpts(kpts, cell, eps=1e-5):
    """Get an x-axis to be used when plotting a band structure.

    The first of the returned lists can be used as a x-axis when plotting
    the band structure. The second list can be used as xticks, and the third
    as xticklabels.

    Parameters:

    kpts: list
        List of scaled k-points.

    cell: list
        Unit cell of the atomic structure.

    Returns:

    Three arrays; the first is a list of cumulative distances between kpoints,
    the second is x coordinates of the special points,
    the third is the special points as strings.
     """
    try:
        crystal_structure = crystal_structure_from_cell(cell)
    except ValueError:
        warnings.warn('Can not recognize your crystal!')
        special_points = {}
    else:
        special_points = get_special_points(crystal_structure, cell)

    points = np.asarray(kpts)
    diffs = points[1:] - points[:-1]
    kinks = abs(diffs[1:] - diffs[:-1]).sum(1) > eps
    N = len(points)
    indices = [0]
    indices.extend(np.arange(1, N - 1)[kinks])
    indices.append(N - 1)

    labels = []
    for kpt in points[indices]:
        for label, k in special_points.items():
            if abs(kpt - k).sum() < eps:
                break
        else:
            label = '?'
        labels.append(label)

    xcoords = [0]
    for i1, i2 in zip(indices[:-1], indices[1:]):
        if i1 + 1 == i2:
            length = 0
        else:
            diff = points[i2] - points[i1]
            length = np.linalg.norm(kpoint_convert(cell, skpts_kc=diff))
        xcoords.extend(np.linspace(0, length, i2 - i1 + 1)[1:] + xcoords[-1])

    xcoords = np.array(xcoords)
    return xcoords, xcoords[indices], labels
Example #3
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)
Example #4
0
def bandpath(path, cell, npoints=50):
    """Make a list of kpoints defining the path between the given points.

    path: list or str
        Can be:

        * a string that parse_path_string() understands: 'GXL'
        * a list of BZ points: [(0, 0, 0), (0.5, 0, 0)]
        * or several lists of BZ points if the the path is not continuous.
    cell: 3x3
        Unit cell of the atoms.
    npoints: int
        Length of the output kpts list.

    Return list of k-points, list of x-coordinates and list of
    x-coordinates of special points."""

    if isinstance(path, basestring):
        xtal = crystal_structure_from_cell(cell)
        special = get_special_points(xtal, cell)
        paths = []
        for names in parse_path_string(path):
            paths.append([special[name] for name in names])
    elif np.array(path[0]).ndim == 1:
        paths = [path]
    else:
        paths = path

    points = np.concatenate(paths)
    dists = points[1:] - points[:-1]
    lengths = [np.linalg.norm(d) for d in kpoint_convert(cell, skpts_kc=dists)]
    i = 0
    for path in paths[:-1]:
        i += len(path)
        lengths[i - 1] = 0

    length = sum(lengths)
    kpts = []
    x0 = 0
    x = []
    X = [0]
    for P, d, L in zip(points[:-1], dists, lengths):
        n = max(2, int(round(L * (npoints - len(x)) / (length - x0))))
        for t in np.linspace(0, 1, n)[:-1]:
            kpts.append(P + t * d)
            x.append(x0 + t * L)
        x0 += L
        X.append(x0)
    kpts.append(points[-1])
    x.append(x0)
    return np.array(kpts), np.array(x), np.array(X)
Example #5
0
def main(args, parser):
    atoms = read(args.calculation)
    cell = atoms.get_cell()
    calc = atoms.calc
    bzkpts = calc.get_bz_k_points()
    ibzkpts = calc.get_ibz_k_points()
    efermi = calc.get_fermi_level()
    nibz = len(ibzkpts)
    nspins = 1 + int(calc.get_spin_polarized())
    eps = np.array([[calc.get_eigenvalues(kpt=k, spin=s)
                     for k in range(nibz)]
                    for s in range(nspins)])
    if not args.quiet:
        print('Spins, k-points, bands: {}, {}, {}'.format(*eps.shape))
    try:
        size, offset = get_monkhorst_pack_size_and_offset(bzkpts)
    except ValueError:
        path = ibzkpts
    else:
        if not args.quiet:
            print('Interpolating from Monkhorst-Pack grid (size, offset):')
            print(size, offset)
        if args.path is None:
            err = 'Please specify a path!'
            try:
                cs = crystal_structure_from_cell(cell)
            except ValueError:
                err += ('\nGPAW cannot autimatically '
                        'recognize this crystal structure')
            else:
                from ase.dft.kpoints import special_paths
                kptpath = special_paths[cs]
                err += ('\nIt looks like you have a {} crystal structure.'
                        '\nMaybe you want its special path:'
                        ' {}'.format(cs, kptpath))
            parser.error(err)
        bz2ibz = calc.get_bz_to_ibz_map()
        path = bandpath(args.path, atoms.cell, args.points)[0]
        icell = atoms.get_reciprocal_cell()
        eps = monkhorst_pack_interpolate(path, eps.transpose(1, 0, 2),
                                         icell, bz2ibz, size, offset)
        eps = eps.transpose(1, 0, 2)

    emin, emax = (float(e) for e in args.range)
    bs = BandStructure(atoms.cell, path, eps, reference=efermi)
    bs.plot(emin=emin, emax=emax)
def generate_kpath_ase(cell, symprec):

    eig_val_max = np.real(np.linalg.eigvals(cell)).max()
    eps = eig_val_max * symprec

    lattice = crystal_structure_from_cell(cell, eps)
    paths = special_paths.get(lattice, None)
    if paths is None:
        paths = special_paths['orthorhombic']
    paths = parse_path_string(special_paths[lattice])
    points = special_points.get(lattice)
    if points is None:
        try:
            points = get_special_points(cell)
        except Exception:
            return []

    return generate_kpath_parameters(points, paths, 100)
Example #7
0
def test_monoclinic():
    """Test band structure from different variations of hexagonal cells."""
    import numpy as np
    from ase import Atoms
    from ase.calculators.test import FreeElectrons
    from ase.geometry import (crystal_structure_from_cell, cell_to_cellpar,
                              cellpar_to_cell)
    from ase.dft.kpoints import get_special_points

    mc1 = [[1, 0, 0], [0, 1, 0], [0, 0.2, 1]]
    par = cell_to_cellpar(mc1)
    mc2 = cellpar_to_cell(par)
    mc3 = [[1, 0, 0], [0, 1, 0], [-0.2, 0, 1]]
    mc4 = [[1, 0, 0], [-0.2, 1, 0], [0, 0, 1]]
    path = 'GYHCEM1AXH1'

    firsttime = True
    for cell in [mc1, mc2, mc3, mc4]:
        a = Atoms(cell=cell, pbc=True)
        a.cell *= 3
        a.calc = FreeElectrons(nvalence=1, kpts={'path': path})
        cs = crystal_structure_from_cell(a.cell)
        assert cs == 'monoclinic'
        r = a.cell.reciprocal()
        k = get_special_points(a.cell)['H']
        print(np.dot(k, r))
        a.get_potential_energy()
        bs = a.calc.band_structure()
        coords, labelcoords, labels = bs.get_labels()
        assert ''.join(labels) == path
        e_skn = bs.energies
        # bs.plot()
        if firsttime:
            coords1 = coords
            labelcoords1 = labelcoords
            e_skn1 = e_skn
            firsttime = False
        else:
            for d in [
                    coords - coords1, labelcoords - labelcoords1,
                    e_skn - e_skn1
            ]:
                print(abs(d).max())
                assert abs(d).max() < 1e-13, d
Example #8
0
def get_cellinfo(cell, lattice=None, eps=2e-4):
    from ase.build.tools import niggli_reduce_cell
    rcell, M = niggli_reduce_cell(cell)
    latt = crystal_structure_from_cell(rcell, niggli_reduce=False)
    if lattice:
        assert latt == lattice.lower(), latt

    if latt == 'monoclinic':
        # Transform From Niggli to Setyawana-Curtarolo cell:
        a, b, c, alpha, beta, gamma = cell_to_cellpar(rcell, radians=True)
        if abs(beta - np.pi / 2) > eps:
            T = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 1]])
            scell = np.dot(T, rcell)
        elif abs(gamma - np.pi / 2) > eps:
            T = np.array([[0, 0, 1], [1, 0, 0], [0, -1, 0]])
        else:
            raise ValueError('You are using a badly oriented ' +
                             'monoclinic unit cell. Please choose one with ' +
                             'either beta or gamma != pi/2')

        scell = np.dot(np.dot(T, rcell), T.T)
        a, b, c, alpha, beta, gamma = cell_to_cellpar(scell, radians=True)

        assert alpha < np.pi / 2, 'Your monoclinic angle has to be < pi / 2'

        M = np.dot(M, T.T)
        eta = (1 - b * cos(alpha) / c) / (2 * sin(alpha)**2)
        nu = 1 / 2 - eta * c * cos(alpha) / b
        points = {
            'G': [0, 0, 0],
            'A': [1 / 2, 1 / 2, 0],
            'C': [0, 1 / 2, 1 / 2],
            'D': [1 / 2, 0, 1 / 2],
            'D1': [1 / 2, 0, -1 / 2],
            'E': [1 / 2, 1 / 2, 1 / 2],
            'H': [0, eta, 1 - nu],
            'H1': [0, 1 - eta, nu],
            'H2': [0, eta, -nu],
            'M': [1 / 2, eta, 1 - nu],
            'M1': [1 / 2, 1 - eta, nu],
            'M2': [1 / 2, eta, -nu],
            'X': [0, 1 / 2, 0],
            'Y': [0, 0, 1 / 2],
            'Y1': [0, 0, -1 / 2],
            'Z': [1 / 2, 0, 0]
        }
    elif latt == 'rhombohedral type 1':
        a, b, c, alpha, beta, gamma = cell_to_cellpar(cell=cell, radians=True)
        eta = (1 + 4 * np.cos(alpha)) / (2 + 4 * np.cos(alpha))
        nu = 3 / 4 - eta / 2
        points = {
            'G': [0, 0, 0],
            'B': [eta, 1 / 2, 1 - eta],
            'B1': [1 / 2, 1 - eta, eta - 1],
            'F': [1 / 2, 1 / 2, 0],
            'L': [1 / 2, 0, 0],
            'L1': [0, 0, -1 / 2],
            'P': [eta, nu, nu],
            'P1': [1 - nu, 1 - nu, 1 - eta],
            'P2': [nu, nu, eta - 1],
            'Q': [1 - nu, nu, 0],
            'X': [nu, 0, -nu],
            'Z': [0.5, 0.5, 0.5]
        }
    else:
        points = ibz_points[latt]

    myspecial_points = {label: np.dot(M, kpt) for label, kpt in points.items()}
    return CellInfo(rcell=rcell, lattice=latt, special_points=myspecial_points)
Example #9
0
assert np.allclose(correct_pos, positions)

# Test center away from values 0, 0.5
result_positions = wrap_positions(positions, cell,
                                  pbc=[True, True, False],
                                  center=0.2)
correct_pos = [[4.7425, 1.2575, 8.7425],
               [2.0275, 3.9725, 8.7425],
               [3.385, 2.615, 10.1],
               [-0.6875, 1.2575, 8.7425],
               [6.1, -0.1, 10.1],
               [3.385, -2.815, 10.1],
               [2.0275, -1.4575, 8.7425],
               [0.67, -0.1, 10.1]]
assert np.allclose(correct_pos, result_positions)

# Get the correct crystal structure from a range of different cells
assert crystal_structure_from_cell(bulk('Al').get_cell()) == 'fcc'
assert crystal_structure_from_cell(bulk('Fe').get_cell()) == 'bcc'
assert crystal_structure_from_cell(bulk('Zn').get_cell()) == 'hexagonal'
cell = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
assert crystal_structure_from_cell(cell) == 'cubic'
cell = [[1, 0, 0], [0, 1, 0], [0, 0, 2]]
assert crystal_structure_from_cell(cell) == 'tetragonal'
cell = [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
assert crystal_structure_from_cell(cell) == 'orthorhombic'
cell = [[1, 0, 0], [0, 2, 0], [0.5, 0, 3]]
assert crystal_structure_from_cell(cell) == 'monoclinic'
cell = [[1, 0, 0], [0.5, 3**0.5 / 2, 0], [0, 0, 3]]
assert crystal_structure_from_cell(cell) == 'hexagonal'
Example #10
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()
Example #11
0
assert np.allclose(correct_pos, positions)

# Test center away from values 0, 0.5
result_positions = wrap_positions(positions, cell,
                                  pbc=[True, True, False],
                                  center=0.2)
correct_pos = [[4.7425, 1.2575, 8.7425],
               [2.0275, 3.9725, 8.7425],
               [3.385, 2.615, 10.1],
               [-0.6875, 1.2575, 8.7425],
               [6.1, -0.1, 10.1],
               [3.385, -2.815, 10.1],
               [2.0275, -1.4575, 8.7425],
               [0.67, -0.1, 10.1]]
assert np.allclose(correct_pos, result_positions)

# Get the correct crystal structure from a range of different cells
assert crystal_structure_from_cell(bulk('Al').get_cell()) == 'fcc'
assert crystal_structure_from_cell(bulk('Fe').get_cell()) == 'bcc'
assert crystal_structure_from_cell(bulk('Zn').get_cell()) == 'hexagonal'
cell = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
assert crystal_structure_from_cell(cell) == 'cubic'
cell = [[1, 0, 0], [0, 1, 0], [0, 0, 2]]
assert crystal_structure_from_cell(cell) == 'tetragonal'
cell = [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
assert crystal_structure_from_cell(cell) == 'orthorhombic'
cell = [[1, 0, 0], [0, 2, 0], [0, 1, 3]]
assert crystal_structure_from_cell(cell) == 'monoclinic'


Example #12
0
"""Test band structure from different variations of hexagonal cells."""
import numpy as np
from ase import Atoms
from ase.calculators.test import FreeElectrons
from ase.geometry import crystal_structure_from_cell
from ase.dft.kpoints import get_special_points

firsttime = True
for cell in [[[1, 0, 0], [0.5, 3**0.5 / 2, 0], [0, 0, 1]],
             [[1, 0, 0], [-0.5, 3**0.5 / 2, 0], [0, 0, 1]],
             [[0.5, -3**0.5 / 2, 0], [0.5, 3**0.5 / 2, 0], [0, 0, 1]]]:
    a = Atoms(cell=cell, pbc=True)
    a.cell *= 3
    a.calc = FreeElectrons(nvalence=1, kpts={'path': 'GMKG'})
    print(crystal_structure_from_cell(a.cell))
    r = a.get_reciprocal_cell()
    k = get_special_points(a.cell)['K']
    print(np.dot(k, r))
    a.get_potential_energy()
    bs = a.calc.band_structure()
    coords, labelcoords, labels = bs.get_labels()
    assert ''.join(labels) == 'GMKG'
    e_skn = bs.energies
    if firsttime:
        coords1 = coords
        labelcoords1 = labelcoords
        e_skn1 = e_skn
        firsttime = False
    else:
        for d in [coords - coords1,
                  labelcoords - labelcoords1,
Example #13
0
def get_special_points(cell, lattice=None, eps=2e-4):
    """Return dict of special points.

    The definitions are from a paper by Wahyu Setyawana and Stefano
    Curtarolo::

        http://dx.doi.org/10.1016/j.commatsci.2010.05.010

    cell: 3x3 ndarray
        Unit cell.
    lattice: str
        Optionally check that the cell is one of the following: cubic, fcc,
        bcc, orthorhombic, tetragonal, hexagonal or monoclinic.
    eps: float
        Tolerance for cell-check.
    """

    if isinstance(cell, str):
        warnings.warn('Please call this function with cell as the first '
                      'argument')
        lattice, cell = cell, lattice

    from ase.build.tools import niggli_reduce_cell
    rcell, M = niggli_reduce_cell(cell)
    latt = crystal_structure_from_cell(rcell, niggli_reduce=False)
    if lattice:
        assert latt == lattice.lower(), latt

    if latt == 'monoclinic':
        # Transform From Niggli to Setyawana-Curtarolo cell:
        a, b, c, alpha, beta, gamma = cell_to_cellpar(rcell, radians=True)
        if abs(beta - np.pi / 2) > eps:
            T = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 1]])
            scell = np.dot(T, rcell)
        elif abs(gamma - np.pi / 2) > eps:
            T = np.array([[0, 0, 1], [1, 0, 0], [0, -1, 0]])
        else:
            raise ValueError('You are using a badly oriented ' +
                             'monoclinic unit cell. Please choose one with ' +
                             'either beta or gamma != pi/2')

        scell = np.dot(np.dot(T, rcell), T.T)
        a, b, c, alpha, beta, gamma = cell_to_cellpar(scell, radians=True)

        assert alpha < np.pi / 2, 'Your monoclinic angle has to be < pi / 2'

        M = np.dot(M, T.T)
        eta = (1 - b * cos(alpha) / c) / (2 * sin(alpha)**2)
        nu = 1 / 2 - eta * c * cos(alpha) / b
        points = {
            'G': [0, 0, 0],
            'A': [1 / 2, 1 / 2, 0],
            'C': [0, 1 / 2, 1 / 2],
            'D': [1 / 2, 0, 1 / 2],
            'D1': [1 / 2, 0, -1 / 2],
            'E': [1 / 2, 1 / 2, 1 / 2],
            'H': [0, eta, 1 - nu],
            'H1': [0, 1 - eta, nu],
            'H2': [0, eta, -nu],
            'M': [1 / 2, eta, 1 - nu],
            'M1': [1 / 2, 1 - eta, nu],
            'M2': [1 / 2, eta, -nu],
            'X': [0, 1 / 2, 0],
            'Y': [0, 0, 1 / 2],
            'Y1': [0, 0, -1 / 2],
            'Z': [1 / 2, 0, 0]
        }
    elif latt == 'rhombohedral type 1':
        a, b, c, alpha, beta, gamma = cell_to_cellpar(cell=cell, radians=True)
        eta = (1 + 4 * np.cos(alpha)) / (2 + 4 * np.cos(alpha))
        nu = 3 / 4 - eta / 2
        points = {
            'G': [0, 0, 0],
            'B': [eta, 1 / 2, 1 - eta],
            'B1': [1 / 2, 1 - eta, eta - 1],
            'F': [1 / 2, 1 / 2, 0],
            'L': [1 / 2, 0, 0],
            'L1': [0, 0, -1 / 2],
            'P': [eta, nu, nu],
            'P1': [1 - nu, 1 - nu, 1 - eta],
            'P2': [nu, nu, eta - 1],
            'Q': [1 - nu, nu, 0],
            'X': [nu, 0, -nu],
            'Z': [0.5, 0.5, 0.5]
        }
    else:
        points = special_points[latt]

    return {label: np.dot(M, kpt) for label, kpt in points.items()}
Example #14
0
def plot_magnon_band(ham,
                     kvectors=np.array([[0, 0, 0], [0.5, 0, 0], [0.5, 0.5, 0],
                                        [0, 0, 0], [.5, .5, .5]]),
                     knames=['$\Gamma$', 'X', 'M', '$\Gamma$', 'R'],
                     supercell_matrix=None,
                     npoints=100,
                     color='red',
                     ax=None,
                     eps=1e-3,
                     kpath_fname=None):
    if ax is None:
        fig, ax = plt.subplots()
    if knames is None or kvectors is None:
        from ase.build.tools import niggli_reduce_cell
        rcell, M = niggli_reduce_cell(ham.cell)
        fcell = fix_cell(ham.cell, eps=eps)
        lattice_type = crystal_structure_from_cell(rcell,
                                                   eps=eps,
                                                   niggli_reduce=False)
        labels = parse_path_string(special_paths[lattice_type])
        knames = [item for sublist in labels for item in sublist]
        kpts, x, X = bandpath(special_paths[lattice_type],
                              rcell,
                              npoints=npoints,
                              eps=1e-8)

        spk = get_special_points(ham.cell, eps=1e-8)
    else:
        kpts, x, X = bandpath(kvectors, fix_cell(ham.cell), npoints)
        spk = dict(zip(knames, kvectors))

    if supercell_matrix is not None:
        kvectors = [np.dot(k, supercell_matrix) for k in kvectors]

    qsolver = QSolver(hamiltonian=ham)
    evals, evecs = qsolver.solve_all(kpts, eigen_vectors=True)
    nbands = evals.shape[1]
    #evecs

    imin = np.argmin(evals[:, 0])
    emin = np.min(evals[:, 0])
    nspin = evals.shape[1] // 3
    evec_min = evecs[imin, :, 0].reshape(nspin, 3)

    # write information to file
    if kpath_fname is not None:
        with open(kpath_fname, 'w') as myfile:
            myfile.write("K-points:\n")
            for name, k in spk.items():
                myfile.write("%s: %s\n" % (name, k))
            myfile.write("\nThe energy minimum is at:")
            myfile.write("%s\n" % kpts[np.argmin(evals[:, 0])])
            for i, ev in enumerate(evec_min):
                myfile.write("spin %s: %s \n" % (i, ev / np.linalg.norm(ev)))
    print("\nThe energy minimum is at:")
    print("%s\n" % kpts[np.argmin(evals[:, 0])])
    print("\n The ground state is:")
    for i, ev in enumerate(evec_min):
        print("spin %s: %s" % (i, ev / np.linalg.norm(ev)))

    for i in range(nbands):
        ax.plot(x, (evals[:, i] - emin) / 1.6e-22)
    ax.set_xlabel('Q-point')
    ax.set_ylabel('Energy (meV)')
    ax.set_xlim(x[0], x[-1])
    ax.set_ylim(0)
    ax.set_xticks(X)
    ax.set_xticklabels(knames)

    for x in X:
        ax.axvline(x, linewidth=0.6, color='gray')
    return ax
Example #15
0
from ase.geometry import crystal_structure_from_cell, cell_to_cellpar, cellpar_to_cell
from ase.dft.kpoints import get_special_points

mc1 = [[1, 0, 0], [0, 1, 0], [0, 0.2, 1]]
par = cell_to_cellpar(mc1)
mc2 = cellpar_to_cell(par)
mc3 = [[1, 0, 0], [0, 1, 0], [-0.2, 0, 1]]
mc4 = [[1, 0, 0], [-0.2, 1, 0], [0, 0, 1]]
path = 'GYHCEM1AXH1'

firsttime = True
for cell in [mc1, mc2, mc3, mc4]:
    a = Atoms(cell=cell, pbc=True)
    a.cell *= 3
    a.calc = FreeElectrons(nvalence=1, kpts={'path': path})
    cs = crystal_structure_from_cell(a.cell)
    assert cs == 'monoclinic'
    r = a.get_reciprocal_cell()
    k = get_special_points(a.cell)['H']
    print(np.dot(k, r))
    a.get_potential_energy()
    bs = a.calc.band_structure()
    coords, labelcoords, labels = bs.get_labels()
    assert ''.join(labels) == path
    e_skn = bs.energies
    # bs.plot()
    if firsttime:
        coords1 = coords
        labelcoords1 = labelcoords
        e_skn1 = e_skn
        firsttime = False
def startMeasurement(filepath, file_type, covalent_radii_cut_off, c, n1, n2,
                     calculate):
    if n1 > n2:
        print("Final m cannot be smaller than initial m")
        return

    print("Starting script...")

    slab = read(filepath)

    total_particles = len(slab)

    print("Slab %s read with success. Total particles %d" %
          (filepath, total_particles))

    print("Creating graph...")

    if file_type == 'V':
        G = generateGraphFromSlabVinkFile(slab, covalent_radii_cut_off)
    else:
        G = generateGraphFromSlab(slab, covalent_radii_cut_off)

    total_nodes = G.get_total_nodes()
    if total_nodes == 0 or G.get_total_edges() == 0:
        print("No edges found in graph. Check covalent_radii_cut_off")
        return

    print("Graph created with success. Nodes found: %d" % total_nodes)

    cell = slab.get_cell()
    crystal_structure = crystal_structure_from_cell(cell)

    if crystal_structure != "ortorhombic" and crystal_structure != "cubic":
        print("Unit cell is not orthorhombic nor cubic")
        return

    measurement = Measurement()
    measurement.fromFile(filepath, covalent_radii_cut_off, c, n1, n2)
    measurement.createFile()

    (pbcX, pbcY, pbcZ) = slab.get_pbc()
    (dmin, dmax) = getMaxMinSlabArray(slab)
    maxM = getNumberRandomPositions(n2 - 1, total_particles)

    configurationalEntropy = bg.ConfigurationalEntropy(G, 3, len(slab), pbcX,
                                                       pbcY, pbcZ, maxM)
    configurationalEntropy.add_positions(slab.get_positions(wrap=True))

    print("Generating random positions...")

    configurationalEntropy.init_search(0, cell[0][0], 0, cell[1][1], 0,
                                       cell[2][2], n2 - 1, maxM, dmin, dmax)

    print("Random positions generated.")

    H_n_values = []
    for n in range(n1, n2):
        measurement.start()

        m = getNumberRandomPositions(n, total_particles)
        H_n, H1n = run(configurationalEntropy, m, n, c)

        measurement.writeResult(n, m, H_n, H1n)
        measurement.end()

        H_n_values.append((n, H_n, H1n, "Y"))

    calculateConfigurationalEntropy(n1, n2, H_n_values, c, calculate)

    print("Program ended correctly")