Пример #1
0
def find_mic(v, cell, pbc=True):
    """Finds the minimum-image representation of vector(s) v using either one
    of two find mic algorithms depending on the given cell, v and pbc."""

    cell = Cell(cell)
    pbc = cell.any(1) & pbc2pbc(pbc)
    dim = np.sum(pbc)
    v = np.asarray(v)
    single = v.ndim == 1
    v = np.atleast_2d(v)

    if dim > 0:
        naive_find_mic_is_safe = False
        if dim == 3:
            vmin, vlen = naive_find_mic(v, cell)
            # naive find mic is safe only for the following condition
            if (vlen < 0.5 * min(cell.lengths())).all():
                naive_find_mic_is_safe = True  # hence skip Minkowski reduction

        if not naive_find_mic_is_safe:
            vmin, vlen = general_find_mic(v, cell, pbc=pbc)
    else:
        vmin = v.copy()
        vlen = np.linalg.norm(vmin, axis=1)

    if single:
        return vmin[0], vlen[0]
    else:
        return vmin, vlen
Пример #2
0
def ase_decoder_hook(dct):
    """JSON decoder hook for ase.Atoms de-serialization."""
    if "__datetime__" in dct:
        return datetime.datetime.strptime(dct["__datetime__"],
                                          "%Y-%m-%dT%H:%M:%S.%f")
    if "__complex__" in dct:
        return complex(*dct["__complex__"])

    if "__ndarray__" in dct:
        return create_ndarray(*dct["__ndarray__"])

    # No longer used (only here for backwards compatibility):
    if "__complex_ndarray__" in dct:
        r, i = (np.array(x) for x in dct["__complex_ndarray__"])
        return r + i * 1j

    if "__ase_objtype__" in dct:
        objtype = dct.pop("__ase_objtype__")
        dct = numpyfy(dct)

        if objtype == "cell":
            from ase.cell import Cell

            pbc = dct.pop("pbc", None)
            obj = Cell(**dct)
            if pbc is not None:
                obj._pbc = pbc
        else:
            raise RuntimeError("Do not know how to decode object type {} "
                               "into an actual object".format(objtype))

        assert obj.ase_objtype == objtype
        return obj

    return dct
Пример #3
0
    def __init__(self, atoms, cellpar, na=1, nb=1, nc=1):
        """
        Create a crystal object.

        A crystal consists of a unit cell and atoms with fractional coordinates. The atoms cartesian coordinates are calculated based on the unit cell (defined by the cell parameters `a`, `b`, `c`, `alpha`, `beta`, and `gamma`) on the fly.

        Parameters
        ----------
        atoms: list
            A list of CIFAtom objects
        cellpar: array-like
            A 6-length array
        na, nb, nc: int
            Bookkeeping numbers for keeping track of how many times the crystal has been "multiplied" - no real use except for when writing MULTEM files
        """
        self.atoms = atoms
        self.cellpar = np.array(cellpar, dtype=float)

        dummy_cell = Cell(np.eye(3))
        self.cell = dummy_cell.new(cell=self.cellpar)
        self.na = na
        self.nb = nb
        self.nc = nc

        site_labels = set([atom.site_label for atom in self.atoms])
        site_keys = site_labels
        self.site_dict = {}
        for label, key in zip(site_labels, site_keys):
            self.site_dict[label] = key
Пример #4
0
    def _variant_name(self, a, b, c, alpha, beta, gamma):
        cell = Cell.new([a, b, c, alpha, beta, gamma])
        icellpar = Cell(cell.reciprocal()).cellpar()
        kangles = kalpha, kbeta, kgamma = icellpar[3:]

        def raise_unconventional():
            raise UnconventionalLattice(
                tri_angles_explanation.format(*kangles))

        eps = self._eps
        if abs(kgamma - 90) < eps:
            if kalpha > 90 and kbeta > 90:
                var = '2a'
            elif kalpha < 90 and kbeta < 90:
                var = '2b'
            else:
                # Is this possible?  Maybe due to epsilon
                raise_unconventional()
        elif all(kangles > 90):
            if kgamma > min(kangles):
                raise_unconventional()
            var = '1a'
        elif all(kangles < 90):  # and kgamma > max(kalpha, kbeta):
            if kgamma < max(kangles):
                raise_unconventional()
            var = '1b'
        else:
            raise_unconventional()

        return 'TRI' + var
Пример #5
0
def find_niggli_ops(latcls, length_grid, angle_grid):
    niggli_ops = {}


    for lat in lattice_loop(latcls, length_grid, angle_grid):
        cell = lat.tocell()

        try:
            rcell, op = cell.niggli_reduce()
        except RuntimeError:
            print('Niggli reduce did not converge')
            continue
        assert op.dtype == int
        op_key = tuple(op.ravel())

        if op_key in niggli_ops:
            niggli_ops[op_key] += 1
        else:
            niggli_ops[op_key] = 1

        rcell_test = Cell(op.T @ cell)
        rcellpar_test = rcell_test.cellpar()
        rcellpar = rcell.cellpar()
        err = np.abs(rcellpar_test - rcellpar).max()
        assert err < 1e-7, err

    return niggli_ops
Пример #6
0
    def convert_units(self, new_units):
        r"""
        Converts the atomic positions in another units.

        Parameters
        ----------
        new_units: str
            The new units in which the positions should be converted.
            Can either be "angstrom" or "atomic".
        """
        if new_units not in ["angstrom", "atomic"]:
            raise ValueError("New units are not recognized.")
        if self.units == new_units:
            pass
        elif self.units == "atomic" and new_units == "angstrom":
            for atom in self:
                atom.position = atom.position * B_TO_ANG
            self.cell = Cell.new(self.cell * B_TO_ANG)
        elif self.units == "angstrom" and new_units == "atomic":
            for atom in self:
                atom.position = atom.position * ANG_TO_B
            self.cell = Cell.new(self.cell * ANG_TO_B)
        elif self.units == "reduced" and new_units == "atomic":
            for atom in self:
                atom.position = np.sum(atom.position * self.cell, axis=0)
        elif self.units == "reduced" and new_units == "angstrom":
            for atom in self:
                atom.position = np.sum(atom.position * self.cell * B_TO_ANG,
                                       axis=0)
            self.cell = Cell.new(self.cell * B_TO_ANG)
        else:
            raise NotImplementedError
        self.units = new_units
Пример #7
0
def kpath(cell, path=None, npoints=None, supercell_matrix=np.eye(3), eps=1e-3):
    mycell = Cell(cell)
    bpath = mycell.bandpath(path=path, npoints=npoints, eps=eps)
    kpts = bpath.kpts
    kpts = [np.dot(kpt, supercell_matrix) for kpt in kpts]
    x, X, knames = bpath.get_linear_kpoint_axis()
    return kpts, x, X, knames
Пример #8
0
 def cell(self, cell):
     if len(cell) == 2:
         cell, angles = cell
     else:
         angles = None
     if isinstance(cell, Cell):
         self._cell = cell
     elif cell is None:
         self._cell = Cell.new()
     elif isinstance(cell, list) or isinstance(cell, np.ndarray):
         if isinstance(cell, list):
             cell = np.array([
                 abs(float(size)) if size not in [".inf", "inf"] else 0.0
                 for size in cell
             ])
         if cell.size == 3 and angles is not None:
             if len(angles) == 3:
                 cell = np.concatenate([cell, angles])
             else:
                 raise ValueError("Need three angles to define a cell.")
         if cell.size in [3, 6, 9]:
             self._cell = Cell.new(cell)
         else:
             raise ValueError(
                 "Cell definition is not valid. See ase.cell.Cell documentation."
             )
     else:
         raise ValueError(
             "Cell definition is not valid. See ase.cell.Cell documentation."
         )
Пример #9
0
def _path_lengths(path: str, cell: Cell, bands_point_num: int) -> List[int]:
    # Construct the metric for reciprocal space (based off Wannier90's "utility_metric" subroutine)
    recip_lat = 2 * math.pi * cell.reciprocal().array
    recip_metric = recip_lat @ recip_lat.T

    # Work out the lengths Wannier90 will assign each path (based off Wannier90's "plot_interpolate_bands" subroutine)
    kpath_pts: List[int] = []
    kpath_len: List[float] = []
    special_points = cell.bandpath().special_points

    path_list = path_str_to_list(path, special_points)

    for i, (start, end) in enumerate(zip(path_list[:-1], path_list[1:])):
        if start == ',':
            kpath_pts.append(0)
        elif end == ',':
            kpath_pts.append(1)
        else:
            vec = special_points[end] - special_points[start]
            kpath_len.append(math.sqrt(vec.T @ recip_metric @ vec))
            if i == 0:
                kpath_pts.append(bands_point_num)
            else:
                kpath_pts.append(int(round(bands_point_num * kpath_len[-1] / kpath_len[0])))
    return kpath_pts
Пример #10
0
    def plot_magnon_band(
        self,
        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=50,
        color='red',
        kpath_fname=None,
        Jq=False,
        ax=None,
    ):
        if ax is None:
            fig, ax = plt.subplots()
        kptlist = kvectors
        if knames is None and kvectors is None:
            # fully automatic k-path
            bp = Cell(self.cell).bandpath(npoints=npoints)
            spk = bp.special_points
            xlist, kptlist, Xs, knames = group_band_path(bp)
        elif knames is not None and kvectors is None:
            # user specified kpath by name
            bp = Cell(self.cell).bandpath(knames, npoints=npoints)
            spk = bp.special_points
            kpts = bp.kpts
            xlist, kptlist, Xs, knames = group_band_path(bp)
        else:
            # user spcified kpath and kvector.
            kpts, x, Xs = bandpath(kvectors, self.cell, npoints)
            spk = dict(zip(knames, kvectors))
            xlist = [x]
            kptlist = [kpts]

        if supercell_matrix is not None:
            kptlist = [np.dot(k, supercell_matrix) for k in kptlist]
        print("High symmetry k-points:")
        for name, k in spk.items():
            if name == 'G':
                name = 'Gamma'
            print(f"{name}: {k}")

        for kpts, xs in zip(kptlist, xlist):
            evals, evecs = self.solve_k(kpts, Jq=Jq)
            # Plot band structure
            nbands = evals.shape[1]
            emin = np.min(evals[:, 0])
            for i in range(nbands):
                ax.plot(xs, (evals[:, i]) / 1.6e-22, color=color)

        ax.set_ylabel('Energy (meV)')
        ax.set_xlim(xlist[0][0], xlist[-1][-1])
        ax.set_xticks(Xs)
        knames = [x if x != 'G' else '$\Gamma$' for x in knames]
        ax.set_xticklabels(knames)
        for x in Xs:
            ax.axvline(x, linewidth=0.6, color='gray')
        return ax
Пример #11
0
def test_line_lattice():
    from ase.cell import Cell
    kx = Cell.new([5, 0, 0]).bandpath(path='GX', npoints=2).kpts
    kz = Cell.new([0, 0, 5]).bandpath(path='GX', npoints=2).kpts
    print(kx)
    print(kz)
    kx[1, 0] -= 0.5
    kz[1, 2] -= 0.5
    assert abs(kx).max() == 0.0
    assert abs(kz).max() == 0.0
Пример #12
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
Пример #13
0
def check_single(name, cell, pbc=None):
    c = Cell(cell, pbc=pbc)
    try:
        lattice = c.get_bravais_lattice()
    except RuntimeError:
        print('error checking {}'.format(name))
        raise
    name1 = lattice.name.lower()
    latname = name.split('@')[0]
    ok = latname == name1
    print(name, '-->', name1, 'OK' if ok else 'ERR', c.cellpar())
    assert ok, 'Expected {latname} but found {name1}'.format(latname, name1)
Пример #14
0
def test_bravais_2d_cell_pbc():
    """Verify 2D Bravais lattice and band path versus pbc information."""

    from ase.cell import Cell

    cell = Cell([[1.,0.,0.],
                 [.1,1.,0.],
                 [0.,0.,0.]])
    lat = cell.get_bravais_lattice()
    print(cell.cellpar())
    print(lat)
    assert lat.name == 'OBL'

    cell[2, 2] = 7
    lat3d = cell.get_bravais_lattice()
    print(lat3d)
    assert lat3d.name == 'MCL'
    lat2d_pbc = cell.get_bravais_lattice(pbc=[1, 1, 0])
    print(lat2d_pbc)
    assert lat2d_pbc.name == 'OBL'

    path = cell.bandpath()
    print(path)

    path2d = cell.bandpath(pbc=[1, 1, 0])
    print(path2d)
    assert path2d.cell.rank == 2
    assert path2d.cell.get_bravais_lattice().name == 'OBL'
Пример #15
0
    def _get_neighbors(self, dx: np.ndarray) -> Iterator[np.ndarray]:
        pbc = self.atoms.pbc
        if self.cell is None or not np.all(self.cell == self.atoms.cell):
            self.cell = self.atoms.cell.array.copy()
            rcell, self.op = minkowski_reduce(complete_cell(self.cell),
                                              pbc=pbc)
            self.rcell = Cell(rcell)
        dx_sc = dx @ self.rcell.reciprocal().T
        offset = np.zeros(3, dtype=np.int32)
        for _ in range(2):
            offset += pbc * ((dx_sc - offset) // 1.).astype(np.int32)

        for ts in product(*[np.arange(-1 * p, p + 1) for p in pbc]):
            yield (np.array(ts) - offset) @ self.op
Пример #16
0
def test_o2b2o():
    import pickle
    import sys
    import unittest
    from ase.db.core import object_to_bytes, bytes_to_object
    from ase.cell import Cell
    import numpy as np

    if sys.version_info < (3, 6):
        # pickles are not sorted
        raise unittest.SkipTest

    for o1 in [
            1.0, {
                'a': np.zeros((2, 2), np.float32),
                'b': np.zeros((0, 2), int)
            }, ['a', 42, True, None, np.nan, np.inf, 1j],
            Cell(np.eye(3)), {
                'a': {
                    'b': {
                        'c': np.ones(3)
                    }
                }
            }
    ]:
        p1 = pickle.dumps(o1)
        b1 = object_to_bytes(o1)
        o2 = bytes_to_object(b1)
        p2 = pickle.dumps(o2)
        print(o2)
        print(b1)
        print()
        assert p1 == p2, (o1, p1, p2, vars(o1), vars(p1), vars(p2))
Пример #17
0
def read_cml(fileobj):
    data = contract(json.load(fileobj))
    atoms = Atoms()
    datoms = data['atoms']

    atoms = Atoms(datoms['elements']['number'])

    if 'unitcell' in data:
        cell = data['unitcell']
        a = cell['a']
        b = cell['b']
        c = cell['c']
        alpha = cell['alpha']
        beta = cell['beta']
        gamma = cell['gamma']
        atoms.cell = Cell.fromcellpar([a, b, c, alpha, beta, gamma])
        atoms.pbc = True

    coords = contract(datoms['coords'])
    if '3d' in coords:
        positions = np.array(coords['3d']).reshape(len(atoms), 3)
        atoms.set_positions(positions)
    else:
        positions = np.array(coords['3dfractional']).reshape(len(atoms), 3)
        atoms.set_scaled_positions(positions)

    yield atoms
def test_bandstructure_transform_mcl(testdir):
    # Test that bandpath() correctly transforms the band path from
    # reference (canonical) cell to actual cell provided by user.

    def _atoms(cell):
        atoms = Atoms(cell=cell, pbc=True)
        atoms.calc = FreeElectrons()
        return atoms

    # MCL with beta > 90, which is a common convention -- but ours is
    # alpha < 90.  We want the bandpath returned by that cell to yield the
    # exact same band structure as our own (alpha < 90) version of the
    # same cell.
    cell = Cell.new([3., 5., 4., 90., 110., 90.])
    lat = cell.get_bravais_lattice()

    density = 10.0
    cell0 = lat.tocell()
    path0 = lat.bandpath(density=density)

    print(cell.cellpar().round(3))
    print(cell0.cellpar().round(3))

    with workdir('files', mkdir=True):
        bs = calculate_band_structure(_atoms(cell),
                                      cell.bandpath(density=density))
        bs.write('bs.json')
        # bs.plot(emin=0, emax=20, filename='fig.bs.svg')

        bs0 = calculate_band_structure(_atoms(cell0), path0)
        bs0.write('bs0.json')
        # bs0.plot(emin=0, emax=20, filename='fig.bs0.svg')

    maxerr = np.abs(bs.energies - bs0.energies).max()
    assert maxerr < 1e-12, maxerr
Пример #19
0
def create_ase_object(objtype, dct):
    # We just try each object type one after another and instantiate
    # them manually, depending on which kind it is.
    # We can formalize this later if it ever becomes necessary.
    if objtype == 'cell':
        from ase.cell import Cell
        dct.pop('pbc', None)  # compatibility; we once had pbc
        obj = Cell(**dct)
    elif objtype == 'bandstructure':
        from ase.spectrum.band_structure import BandStructure
        obj = BandStructure(**dct)
    elif objtype == 'bandpath':
        from ase.dft.kpoints import BandPath
        obj = BandPath(path=dct.pop('labelseq'), **dct)
    elif objtype == 'atoms':
        from ase import Atoms
        obj = Atoms.fromdict(dct)
    elif objtype == 'densityofstates':
        from ase.dft.dos import DOS
        obj = DOS(**dct)
    elif objtype == 'griddoscollection':
        from ase.spectrum.doscollection import GridDOSCollection
        obj = GridDOSCollection.fromdict(dct)
    else:
        raise ValueError('Do not know how to decode object type {} '
                         'into an actual object'.format(objtype))
    assert obj.ase_objtype == objtype
    return obj
Пример #20
0
def test_bravais_eps():
    import numpy as np
    from ase.cell import Cell

    # This tests a BCT cell which would be mischaracterized as MCLC
    # depending on comparson's precision (fix: c432fd52ecfdca).
    # The cell should actually be MCLC for small tolerances,
    # and BCT with larger ones.  But it would always come out MCLC.
    #
    # The solution is that the Niggli reduction must run with a more
    # coarse precision than the lattice recognition algorithm.
    #
    # Danger: Since the two mechanisms (Niggli, lattice recognition)
    # define their precisions differently, it is not certain whether this
    # problem is entirely gone.
    cellpar = np.array([3.42864, 3.42864, 3.42864, 125.788, 125.788, 80.236])
    cell = Cell.new(cellpar)
    mclc = cell.get_bravais_lattice(eps=1e-4)
    bct = cell.get_bravais_lattice(eps=1e-3)

    print(mclc)
    print(bct)
    assert mclc.name == 'MCLC'
    assert bct.name == 'BCT'

    # Original cell is not perfect (rounding).
    perfect_bct_cell = bct.tocell()
    # perfect_bct_cellpar = bct.cellpar()
    assert perfect_bct_cell.get_bravais_lattice().name == 'BCT'
Пример #21
0
def object_hook(dct):
    if '__datetime__' in dct:
        return datetime.datetime.strptime(dct['__datetime__'],
                                          '%Y-%m-%dT%H:%M:%S.%f')
    if '__complex_ndarray__' in dct:
        r, i = (np.array(x) for x in dct['__complex_ndarray__'])
        return r + i * 1j

    if '__ase_objtype__' in dct:
        objtype = dct.pop('__ase_objtype__')
        dct = numpyfy(dct)

        # We just try each object type one after another and instantiate
        # them manually, depending on which kind it is.
        # We can formalize this later if it ever becomes necessary.
        if objtype == 'cell':
            from ase.cell import Cell
            obj = Cell(**dct)
        elif objtype == 'bandstructure':
            from ase.dft.band_structure import BandStructure
            obj = BandStructure(**dct)
        elif objtype == 'bandpath':
            from ase.dft.kpoints import BandPath
            obj = BandPath(path=dct.pop('labelseq'), **dct)
        else:
            raise RuntimeError('Do not know how to decode object type {} '
                               'into an actual object'.format(objtype))

        assert obj.ase_objtype == objtype
        return obj

    return dct
Пример #22
0
    def get_qm_cluster(self, atoms):

        if self.qm_buffer_mask is None:
            self.initialize_qm_buffer_mask(atoms)

        qm_cluster = atoms[self.qm_buffer_mask]
        del qm_cluster.constraints

        round_cell = False
        if self.qm_radius is None:
            round_cell = True
            # get all distances between qm atoms.
            # Treat all X, Y and Z directions independently
            # only distance between qm atoms is calculated
            # in order to estimate qm radius in thee directions
            R_qm, _ = get_distances(atoms.positions[self.qm_selection_mask],
                                    cell=atoms.cell,
                                    pbc=atoms.pbc)
            # estimate qm radius in three directions as 1/2
            # of max distance between qm atoms
            self.qm_radius = np.amax(np.amax(R_qm, axis=1), axis=0) * 0.5

        if atoms.cell.orthorhombic:
            cell_size = np.diagonal(atoms.cell)
        else:
            raise RuntimeError("NON-orthorhombic cell is not supported!")

        # check if qm_cluster should be left periodic
        # in periodic directions of the cell (cell[i] < qm_radius + buffer
        # otherwise change to non pbc
        # and make a cluster in a vacuum configuration
        qm_cluster_pbc = (atoms.pbc & (cell_size < 2.0 *
                                       (self.qm_radius + self.buffer_width)))

        # start with the original orthorhombic cell
        qm_cluster_cell = cell_size.copy()
        # create a cluster in a vacuum cell in non periodic directions
        qm_cluster_cell[~qm_cluster_pbc] = (2.0 *
                                            (self.qm_radius[~qm_cluster_pbc] +
                                             self.buffer_width + self.vacuum))

        if round_cell:
            # round the qm cell to the required tolerance
            qm_cluster_cell[~qm_cluster_pbc] = (np.round(
                (qm_cluster_cell[~qm_cluster_pbc]) / self.qm_cell_round_off) *
                                                self.qm_cell_round_off)

        qm_cluster.set_cell(Cell(np.diag(qm_cluster_cell)))
        qm_cluster.pbc = qm_cluster_pbc

        qm_shift = (0.5 * qm_cluster.cell.diagonal() -
                    qm_cluster.positions.mean(axis=0))

        if 'cell_origin' in qm_cluster.info:
            del qm_cluster.info['cell_origin']

        # center the cluster only in non pbc directions
        qm_cluster.positions[:, ~qm_cluster_pbc] += qm_shift[~qm_cluster_pbc]

        return qm_cluster
Пример #23
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
Пример #24
0
def test_standard_form():
    import numpy as np
    from numpy.testing import assert_allclose
    from ase.cell import Cell

    TOL = 1E-10
    rng = np.random.RandomState(0)

    for i in range(20):
        cell0 = rng.uniform(-1, 1, (3, 3))
        for sign in [-1, 1]:
            cell = Cell(sign * cell0)
            rcell, Q = cell.standard_form()
            assert_allclose(rcell @ Q, cell, atol=TOL)
            assert_allclose(np.linalg.det(rcell), np.linalg.det(cell))
            assert_allclose(rcell.ravel()[[1, 2, 5]], 0, atol=TOL)
Пример #25
0
 def get_vectors(self):
     x, y, z = self.cell_grid
     cell = np.array(
         [[x[0].value, x[1].value, x[2].value],
          [y[0].value, y[1].value, y[2].value],
          [z[0].value, z[1].value, z[2].value]]
     )
     return Cell(cell)
Пример #26
0
def format_cell(cell: Cell) -> str:
    assert cell.rank == 3
    lines = []
    for name, value in zip(CIFBlock.cell_tags, cell.cellpar()):
        line = '{:20} {:g}\n'.format(name, value)
        lines.append(line)
    assert len(lines) == 6
    return ''.join(lines)
Пример #27
0
    def test_1d(self, axis):
        lcell = self.lcell
        rcell, op = minkowski_reduce(lcell, pbc=np.roll([1, 0, 0], axis))
        assert (rcell == lcell).all()  # 1D reduction does nothing

        zcell = np.zeros((3, 3))
        zcell[0] = lcell[0]
        rcell, _ = Cell(zcell).minkowski_reduce()
        assert_allclose(rcell, zcell, atol=TOL)
Пример #28
0
    def check_single(name, cell, pbc=None):
        c = Cell(cell)

        try:
            print('TEST', c, pbc)
            if pbc[:2].all() or sum(pbc) == 1:
                lattice = c.get_bravais_lattice(pbc=pbc)
            else:
                with must_raise(UnsupportedLattice):
                    lattice = c.get_bravais_lattice(pbc=pbc)
                return
        except RuntimeError:
            print('error checking {}'.format(name))
            raise
        name1 = lattice.name.lower()
        latname = name.split('@')[0]
        ok = latname == name1
        print(name, '-->', name1, 'OK' if ok else 'ERR', c.cellpar())
        assert ok, 'Expected {} but found {}'.format(latname, name1)
Пример #29
0
    def update(self, cell, pbc):
        cell = Cell(cell)
        mags = cell.lengths()
        angles = cell.angles()

        for i in range(3):
            for j in range(3):
                if np.isnan(cell[i][j]):
                    cell[i][j] = 0
                self.cell_grid[i][j].value = cell[i][j]

            if np.isnan(mags[i]):
                mags[i] = 0
            self.cell_grid[i][3].value = mags[i]

            if np.isnan(angles[i]):
                angles[i] = 0
            self.angles[i].value = angles[i]

            self.pbc[i].var.set(bool(pbc[i]))
Пример #30
0
    def test_2d(self, axis):
        lcell = self.lcell
        pbc = np.roll([0, 1, 1], axis)
        rcell, op = minkowski_reduce(lcell.astype(float), pbc=pbc)
        assert (rcell[axis] == lcell[axis]).all()

        zcell = np.copy(lcell)
        zcell[axis] = 0
        rzcell, _ = Cell(zcell).minkowski_reduce()
        rcell[axis] = 0
        assert_allclose(rzcell, rcell, atol=TOL)