Пример #1
0
def celldiff(cell1, cell2):
    """Return a unitless measure of the difference between two cells."""
    cell1 = Cell.ascell(cell1).complete()
    cell2 = Cell.ascell(cell2).complete()
    v1v2 = cell1.volume * cell2.volume
    scale = v1v2**(-1. / 3.)  # --> 1/Ang^2
    x1 = cell1 @ cell1.T
    x2 = cell2 @ cell2.T
    dev = scale * np.abs(x2 - x1).max()
    return dev
Пример #2
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

    cell = Cell.ascell(cell)
    # We create the bandpath because we want to transform the kpoints too,
    # from the canonical cell to the given one.
    #
    # Note that this function is missing a tolerance, epsilon.
    path = cell.bandpath(npoints=0)
    return path.special_points
Пример #3
0
def get_bravais_lattice(cell, eps=2e-4):
    cell = Cell.ascell(cell)

    if cell.pbc.all():
        lat, op = identify_lattice(cell, eps=eps)
    elif cell.pbc[:2].all():
        lat, op = get_2d_bravais_lattice(cell, eps)
    else:
        raise ValueError('Cell must be periodic either along two first '
                         'axes or along all three.  Got pbc={}'.format(
                             cell.pbc))
    return lat
Пример #4
0
def bandpath(path,
             cell,
             npoints=None,
             density=None,
             special_points=None,
             eps=2e-4):
    """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. If too small, at least the beginning
        and ending point of each path segment will be used. If None (default),
        it will be calculated using the supplied density or a default one.
    density: float
        k-points per 1/A on the output kpts list. If npoints is None,
        the number of k-points in the output list will be:
        npoints = density * path total length (in Angstroms).
        If density is None (default), use 5 k-points per A⁻¹.
        If the calculated npoints value is less than 50, a minimum value of 50
        will be used.
    special_points: dict or None
        Dictionary mapping names to special points.  If None, the special
        points will be derived from the cell.
    eps: float
        Precision used to identify Bravais lattice, deducing special points.

    You may define npoints or density but not both.

    Return a :class:`~ase.dft.kpoints.BandPath` object."""

    cell = Cell.ascell(cell)
    return cell.bandpath(path,
                         npoints=npoints,
                         density=density,
                         special_points=special_points,
                         eps=eps)
Пример #5
0
def kpts2kpts(kpts, atoms=None):
    if kpts is None:
        return KPoints()

    if hasattr(kpts, 'kpts'):
        return kpts

    if isinstance(kpts, dict):
        if 'kpts' in kpts:
            return KPoints(kpts['kpts'])
        if 'path' in kpts:
            cell = Cell.ascell(atoms.cell)
            return cell.bandpath(pbc=atoms.pbc, **kpts)
        size, offsets = kpts2sizeandoffsets(atoms=atoms, **kpts)
        return KPoints(monkhorst_pack(size) + offsets)

    if isinstance(kpts[0], int):
        return KPoints(monkhorst_pack(kpts))

    return KPoints(np.array(kpts))
Пример #6
0
 def checkcell(cell, name):
     cell = Cell.ascell(cell)
     lat = cell.get_bravais_lattice()
     assert lat.name == name, (lat.name, name)
Пример #7
0
def bandpath(path, cell, npoints=None, density=None, special_points=None,
             eps=2e-4):
    """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. If too small, at least the beginning
        and ending point of each path segment will be used. If None (default),
        it will be calculated using the supplied density or a default one.
    density: float
        k-points per A⁻¹ on the output kpts list. If npoints is None,
        the number of k-points in the output list will be:
        npoints = density * path total length (in Angstroms).
        If density is None (default), use 5 k-points per A⁻¹.
        If the calculated npoints value is less than 50, a minimum value of 50
        will be used.
    special_points: dict or None
        Dictionary mapping names to special points.  If None, the special
        points will be derived from the cell.
    eps: float
        Precision used to identify Bravais lattice, deducing special points.

    You may define npoints or density but not both.

    Return a :class:`~ase.dft.kpoints.BandPath` object."""

    cell = Cell.ascell(cell)
    return cell.bandpath(path, npoints=npoints, density=density,
                         special_points=special_points, eps=eps)

    # XXX old code for bandpath() function, should be removed once we
    # weed out any trouble
    if isinstance(path, str):
        # XXX we need to update this so we use the new and more complete
        # cell classification stuff
        lattice = None
        if special_points is None:
            cell = Cell.ascell(cell)
            cellinfo = get_cellinfo(cell)
            special_points = cellinfo.special_points
            lattice = cellinfo.lattice
        paths = []
        for names in parse_path_string(path):
            for name in names:
                if name not in special_points:
                    msg = ('K-point label {} not included in {} special '
                           'points.  Valid labels are: {}'
                           .format(name, lattice or 'custom dictionary of',
                                   ', '.join(sorted(special_points))))
                    raise ValueError(msg)
            paths.append([special_points[name] for name in names])
    elif np.array(path[0]).ndim == 1:
        paths = [path]
    else:
        paths = path

    kpts, x, X = paths2kpts(paths, cell, npoints, density)
    return BandPath(cell, kpts=kpts, special_points=special_points)