Exemplo n.º 1
0
    def minkowski_reduce(self):
        """Minkowski-reduce this cell, returning new cell and mapping.

        See also :func:`ase.geometry.minkowski_reduction.minkowski_reduce`."""
        from ase.geometry.minkowski_reduction import minkowski_reduce
        rcell, op = minkowski_reduce(self)
        return Cell(rcell), op
Exemplo n.º 2
0
def find_mic(v, cell, pbc=True):
    """Finds the minimum-image representation of vector(s) v"""

    pbc = cell.any(1) & pbc2pbc(pbc)
    v = np.array(v)
    single = len(v.shape) == 1
    v = np.atleast_2d(v)

    if np.sum(pbc) > 0:
        cell = complete_cell(cell)
        rcell, _ = minkowski_reduce(cell, pbc=pbc)

        # in a Minkowski-reduced cell we only need to test nearest neighbors
        cs = [np.arange(-1 * p, p + 1) for p in pbc]
        neighbor_cells = list(itertools.product(*cs))

        positions = wrap_positions(v, rcell, pbc=pbc, eps=0)
        vmin = positions.copy()
        vlen = np.linalg.norm(positions, axis=1)
        for nbr in neighbor_cells:
            trial = positions + np.dot(rcell.T, nbr)
            trial_len = np.linalg.norm(trial, axis=1)

            indices = np.where(trial_len < vlen)
            vmin[indices] = trial[indices]
            vlen[indices] = trial_len[indices]
    else:
        vmin = v.copy()
        vlen = np.linalg.norm(vmin, axis=1)

    if single:
        return vmin[0], vlen[0]
    else:
        return vmin, vlen
Exemplo n.º 3
0
def general_find_mic(v, cell, pbc=True):
    """Finds the minimum-image representation of vector(s) v. Using the
    Minkowski reduction the algorithm is relatively slow but safe for any cell.
    """

    cell = complete_cell(cell)
    rcell, _ = minkowski_reduce(cell, pbc=pbc)
    positions = wrap_positions(v, rcell, pbc=pbc, eps=0)

    # In a Minkowski-reduced cell we only need to test nearest neighbors,
    # or "Voronoi-relevant" vectors. These are a subset of combinations of
    # [-1, 0, 1] of the reduced cell vectors.

    # Define ranges [-1, 0, 1] for periodic directions and [0] for aperiodic
    # directions.
    ranges = [np.arange(-1 * p, p + 1) for p in pbc]

    # Get Voronoi-relevant vectors.
    # Pre-pend (0, 0, 0) to resolve issue #772
    hkls = np.array([(0, 0, 0)] + list(itertools.product(*ranges)))
    vrvecs = hkls @ rcell

    # Map positions into neighbouring cells.
    x = positions + vrvecs[:, None]

    # Find minimum images
    lengths = np.linalg.norm(x, axis=2)
    indices = np.argmin(lengths, axis=0)
    vmin = x[indices, np.arange(len(positions)), :]
    vlen = lengths[indices, np.arange(len(positions))]
    return vmin, vlen
Exemplo n.º 4
0
    def minkowski_reduce(self):
        """Minkowski-reduce this cell, returning new cell and mapping.

        See also :func:`ase.geometry.minkowski_reduction.minkowski_reduce`."""
        from ase.geometry.minkowski_reduction import minkowski_reduce
        cell, op = minkowski_reduce(self, self.any(1))
        result = Cell(cell)
        return result, op