コード例 #1
0
ファイル: test_spglib.py プロジェクト: xj361685640/octopus
 def test_standardize_cell_from_primitive(self):
     for fname in self._filenames:
         spgnum = int(fname.split('-')[1])
         cell = read_vasp("./data/%s" % fname)
         if 'distorted' in fname:
             prim_cell = standardize_cell(cell,
                                          to_primitive=True,
                                          no_idealize=True,
                                          symprec=1e-1)
             std_cell = standardize_cell(prim_cell,
                                         to_primitive=False,
                                         no_idealize=True,
                                         symprec=1e-1)
             dataset = get_symmetry_dataset(std_cell, symprec=1e-1)
         else:
             prim_cell = standardize_cell(cell,
                                          to_primitive=True,
                                          no_idealize=True,
                                          symprec=1e-5)
             std_cell = standardize_cell(prim_cell,
                                         to_primitive=False,
                                         no_idealize=True,
                                         symprec=1e-5)
             dataset = get_symmetry_dataset(std_cell, symprec=1e-5)
         self.assertEqual(dataset['number'], spgnum, msg=("%s" % fname))
コード例 #2
0
 def test_standardize_cell_from_primitive(self):
     for fname, spgnum in zip(self._filenames, self._spgnum_ref):
         cell = read_vasp(fname)
         if 'distorted' in fname:
             prim_cell = standardize_cell(cell,
                                          to_primitive=True,
                                          no_idealize=True,
                                          symprec=1e-1)
             std_cell = standardize_cell(prim_cell,
                                         to_primitive=False,
                                         no_idealize=True,
                                         symprec=1e-1)
             dataset = get_symmetry_dataset(std_cell, symprec=1e-1)
         else:
             prim_cell = standardize_cell(cell,
                                          to_primitive=True,
                                          no_idealize=True,
                                          symprec=1e-5)
             std_cell = standardize_cell(prim_cell,
                                         to_primitive=False,
                                         no_idealize=True,
                                         symprec=1e-5)
             dataset = get_symmetry_dataset(std_cell, symprec=1e-5)
         self.assertEqual(dataset['number'], spgnum,
                          msg=("%s" % fname))
コード例 #3
0
def test_spglib_standardize():
    for i in [
            "../tests/MoS2_2H_1l.xyz",
            "../tests/WS2_2H_1l.xyz",
            "../tests/graphene.xyz",
    ]:
        atoms = ase.io.read(PROJECT_ROOT_DIR.joinpath(i))
        N = [[3, 1, 0], [-1, 2, 0], [0, 0, 1]]
        sc = make_supercell(atoms, N)
        cppatoms = ase_atoms_to_cpp_atoms(sc)
        cppatoms.standardize(1, 0, 1e-5, 5)

        cell = (sc.cell, sc.get_scaled_positions(), sc.numbers)
        spgcell = spglib.standardize_cell(cell,
                                          to_primitive=True,
                                          no_idealize=False,
                                          symprec=1e-5,
                                          angle_tolerance=5)
        atoms = Atoms(
            cell=spgcell[0],
            scaled_positions=spgcell[1],
            numbers=spgcell[2],
            pbc=[True, True, True],
        )
        cppatoms = cpp_atoms_to_ase_atoms(cppatoms)
        comp = SymmetryEquivalenceCheck()
        is_equal = comp.compare(atoms, cppatoms)
        assert (
            is_equal
        ), "Standardization in backend and from spglib do not yield same result."
コード例 #4
0
ファイル: firetasks.py プロジェクト: tsaie79/pytopomat
    def run_task(self, fw_spec):

        wd = os.getcwd()

        struct = Structure.from_file(wd + "/POSCAR")

        numbers = [site.specie.number for site in struct]
        lattice = struct.lattice.matrix
        positions = struct.frac_coords

        if "magmom" in struct.site_properties:
            magmoms = struct.site_properties["magmom"]
            cell = (lattice, positions, numbers, magmoms)
        else:
            magmoms = None
            cell = (lattice, positions, numbers)

        lat, pos, nums = standardize_cell(cell, to_primitive=False, symprec=1e-2)

        structure = Structure(lat, nums, pos)

        if magmoms is not None:
            structure.add_site_property("magmom", magmoms)

        structure.to(fmt="poscar", filename="CONTCAR")

        return FWAction(update_spec={"structure": structure})
コード例 #5
0
    def get_primitive_cell(self,
                           standardize=False,
                           use_elements=None,
                           use_magmoms=None):
        """
        Get primitive cell of a given structure.

        Args:
            standardize (bool): Get orthogonal box
            use_magmoms (bool): Whether to consider magnetic moments (cf.
            get_initial_magnetic_moments())
            use_elements (bool): If False, chemical elements will be ignored

        Returns:
            (pyiron_atomistics.atomistics.structure.atoms.Atoms): Primitive cell

        Example (assume `basis` is a primitive cell):

        >>> structure = basis.repeat(2)
        >>> symmetry = Symmetry(structure)
        >>> len(symmetry.get_primitive_cell()) == len(basis)
        True
        """
        cell, positions, indices = spglib.standardize_cell(
            self._get_spglib_cell(use_elements=use_elements,
                                  use_magmoms=use_magmoms),
            to_primitive=not standardize,
        )
        positions = (cell.T @ positions.T).T
        new_structure = self._structure.copy()
        new_structure.cell = cell
        new_structure.indices[:len(indices)] = indices
        new_structure = new_structure[:len(indices)]
        new_structure.positions = positions
        return new_structure
コード例 #6
0
def main(fxyz, prefix, verbose, precision):
    # read frames
    if fxyz != 'none':
        frames = read(fxyz, ':')
        nframes = len(frames)
        print("read xyz file:", fxyz, ", a total of", nframes, "frames")

    standardized_frames = []

    for frame in frames:
        space_now = spglib.get_spacegroup(
            frame,
            symprec=precision)  # spglib.get_symmetry(frame, symprec=1e-1))
        print(space_now)
        lattice, scaled_positions, numbers = spglib.standardize_cell(
            frame, to_primitive=1, no_idealize=1, symprec=precision)
        if verbose:
            show_cell(lattice, scaled_positions, numbers)
        # output
        frtemp = atom(numbers=numbers,
                      cell=lattice,
                      scaled_positions=scaled_positions,
                      pbc=frame.get_pbc())
        frtemp.info['space_group'] = space_now
        standardized_frames.append(frtemp)

    write(prefix + '-standardized.xyz', standardized_frames)
コード例 #7
0
    def conventional(self, symprec=1e-5):
        """
        conventional structure
        
        Arugments:
            symprec (symmetry tolerance): distance tolerance in Cartesian coordinates to find crystal symmetry 
        """
        cell = self.structure.formatting('cell')
        cell = (cell['lattice'], cell['positions'], cell['numbers'])

        # method 1
        lattice, scaled_positions, numbers = spglib.standardize_cell(
            cell, symprec=symprec)
        newcell = (lattice, scaled_positions, numbers)
        # method 2
        #newcell=spglib.standardize_cell(cell, symprec=symprec)

        if newcell == None:
            raise StructureFactoryError('The search is failed')
        else:
            poscar = self.__toPOSCAR(newcell)

            self.structure.pop()  # delete old object
            self.structure = Structure().append(poscar)
            return self.structure
コード例 #8
0
ファイル: optimize.py プロジェクト: jtsun/aiida-phonopy
def standardize_cell(structure):
    import spglib
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy.structure.atoms import atom_data

    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    structure_data = (structure.cell,
                      bulk.get_scaled_positions(),
                      bulk.get_atomic_numbers())

    #lattice, refined_positions, numbers = spglib.refine_cell(structure_data, symprec=1e-5)
    lattice, standardized_positions, numbers = spglib.standardize_cell(structure_data,
                                                                       symprec=1e-5,
                                                                       to_primitive=False,
                                                                       no_idealize=False)

    symbols = [atom_data[i][1] for i in numbers]

    # print lattice, standardized_positions, numbers
    # print [site.kind_name for site in structure.sites]
    standardized_bulk = PhonopyAtoms(symbols=symbols,
                                     scaled_positions=standardized_positions,
                                     cell=lattice)

    # create new aiida structure object
    standarized = StructureData(cell=standardized_bulk.get_cell())
    for position, symbol in zip(standardized_bulk.get_positions(), standardized_bulk.get_chemical_symbols()):
        standarized.append_atom(position=position,
                                      symbols=symbol)

    return {'standardized_structure': standarized}
コード例 #9
0
def cell_to_primitive(cell_or_dataset,
                      symprec=1e-3,
                      angle_tolerance=-1.0,
                      hall_number=0,
                      message=True):
    '''Convert a cell to a primitive cell'''

    if isinstance(cell_or_dataset, dict):
        dataset = cell_or_dataset
    else:
        cell = tuple(cell_or_dataset)
        dataset = spglib.get_symmetry_dataset(cell,
                                              symprec=symprec,
                                              angle_tolerance=angle_tolerance,
                                              hall_number=hall_number)

    # Construct a primitive cell object
    std_lattice = dataset['std_lattice']
    std_positions = dataset['std_positions']
    std_types = dataset['std_types']
    std_cell = (std_lattice, std_positions, std_types)

    lattice, scaled_positions, numbers = spglib.standardize_cell(
        std_cell, to_primitive=True, no_idealize=True, symprec=symprec)
    primitive_cell = (lattice, scaled_positions, numbers)

    if message:
        if compare_cells(cell, primitive_cell):
            print(
                'The unit cell was a primitive cell. However, the primitive cell computed by spglib is returned, it is maybe not the same as the provided unit cell'
            )
        else:
            print('The unit cell was transformed to a primitive cell')

    return primitive_cell
コード例 #10
0
    def primitive(self, symprec=1e-2):
        """ 
        Returns a Crystal object in the primitive unit cell.
        
        Parameters
        ----------
        symprec : float, optional
            Symmetry-search distance tolerance in Cartesian coordinates [Angstroms].

        Returns
        -------
        primitive : Crystal
            Crystal with primitive cell. Even if the crystal already has a primitive
            cell, a new crystal is returned.

        Raises
        ------
        RuntimeError : If primitive cell could not be found.
        
        Notes
        -----
        Optional atomic properties (e.g magnetic moment) might be lost in the reduction.
        """
        search = standardize_cell(self._spglib_cell(),
                                  to_primitive=True,
                                  no_idealize=True,
                                  symprec=symprec)
        if search is None:
            raise RuntimeError("Primitive cell could not be found.")

        return self._from_spglib_cell(*search, source=self.source)
コード例 #11
0
ファイル: make_conv_cell.py プロジェクト: wangvei/elastool
def make_conventional_cell(file_name_read):
    if file_name_read.split('.')[-1] == 'vasp':
        input_file_format = 'vasp'
    elif file_name_read.split('.')[-1] == 'cif':
        input_file_format = 'cif'
    else:
        print('Please provide correct file name: .vasp or .cif')
        exit(1)

    file_read = open(file_name_read, 'r')

    if input_file_format == 'vasp':
        pos = vasp.read_vasp(file_read)
    elif input_file_format == 'cif':
        pos = io.read(file_read, format='cif')

    if indict['dimensional'][0] == '3D':
        if indict['if_conventional_cell'][0] == 'yes':
            to_primitive = False
        elif indict['if_conventional_cell'][0] == 'no':
            to_primitive = True

        pos_std = standardize_cell(pos, to_primitive=to_primitive)
        pos_conv = Atoms(pos_std[2], scaled_positions=pos_std[1], cell=pos_std[0])

    elif indict['dimensional'][0] == '2D':
        pos_conv = pos

    return pos_conv
    
コード例 #12
0
def standardize_cell(structure,
                     to_primitive=True,
                     no_idealize=False,
                     symprec=1e-3,
                     verbosity=0):
    """
    Standardizes the input crystal structure using `spglib`.

    Args:
        structure: :class:`simulation.Structure` object with a crystal structure.
        to_primitive: Boolean specifying whether to convert the input structure
            to a primitive unit cell.
        no_idealize: Boolean specifying whether to "idealize" lattice vectors,
            angles according to the ITC.
        symprec: Float with the Cartesian distance tolerance.
        verbosity: Integer with the level of standard output verbosity.

    Returns: :class:`simulation.Structure` object with the standardized unit cell
        if successful, the input structure as is, otherwise.

    """
    _check_spglib_install()
    rev_lookup = dict(
        zip(structure.site_comp_indices, structure.site_compositions))
    cell = spglib.standardize_cell(_structure_to_cell(structure),
                                   to_primitive=to_primitive,
                                   no_idealize=no_idealize,
                                   symprec=symprec)
    if not _check_spglib_success(cell, verbosity=verbosity):
        return structure
    _cell_to_structure(cell, structure, rev_lookup)
    return structure
コード例 #13
0
    def ideal(self, symprec=1e-2):
        """ 
        Returns a Crystal object with an idealized unit cell.
        
        Parameters
        ----------
        symprec : float, optional
            Symmetry-search distance tolerance in Cartesian coordinates [Angstroms].

        Returns
        -------
        ideal : Crystal
            Crystal with idealized cell. 

        Raises
        ------
        RuntimeError : If an ideal cell could not be found.
        
        Notes
        -----
        Optional atomic properties (e.g magnetic moment) might be lost in the symmetrization.
        """
        search = standardize_cell(self._spglib_cell(),
                                  to_primitive=True,
                                  no_idealize=False,
                                  symprec=symprec)
        if search is None:
            raise RuntimeError("Ideal cell could not be found.")

        return self._from_spglib_cell(*search, source=self.source)
コード例 #14
0
ファイル: crystal.py プロジェクト: peterspackman/chmpy
def standardize_crystal(crystal, method="spglib", **kwargs):
    if method != "spglib":
        raise NotImplementedError("Only spglib is currently supported")

    lattice = crystal.unit_cell.direct
    uc_dict = crystal.unit_cell_atoms()
    positions = uc_dict["frac_pos"]
    elements = uc_dict["element"]
    asym_atoms = uc_dict["asym_atom"]
    asym_labels = uc_dict["label"]
    cell = lattice, positions, elements

    reduced_cell = standardize_cell(cell, **kwargs)

    if reduced_cell is None:
        LOG.warn("Could not find reduced cell for crystal %s", crystal)
        return None
    dataset = get_symmetry_dataset(reduced_cell)
    asym_idx = np.unique(dataset["equivalent_atoms"])
    asym_idx = asym_idx[np.argsort(asym_atoms[asym_idx])]
    sg = SpaceGroup(dataset["number"], choice=dataset["choice"])

    reduced_lattice, positions, elements = reduced_cell
    unit_cell = UnitCell(reduced_lattice)
    asym = AsymmetricUnit(
        [Element[x] for x in elements[asym_idx]],
        positions[asym_idx],
        labels=asym_labels[asym_idx],
    )
    return Crystal(unit_cell, sg, asym)
コード例 #15
0
ファイル: ciflib.py プロジェクト: pearcandy/ciflib
def calc_check(cell, spgnum, tol=1.0e-5):
    print('\n[primitive cell (calc)]')
    print_cell(cell)
    dataset = spglib.get_symmetry_dataset(cell, tol)
    spgnum_pcell = dataset['number']
    hallnum_pcell = dataset['hall_number']
    print_dataset(dataset)

    print('\n[conventional cell (calc pcell+standardize)]')
    scell = spglib.standardize_cell(cell)
    print_cell(scell)
    dataset = spglib.get_symmetry_dataset(scell, tol)
    spgnum_ccell = dataset['number']
    hallnum_ccell = dataset['hall_number']
    print_dataset(dataset)

    print('\n# check crystal structure...')
    print('%-25s %10s %10s' % ('', 'spg num', 'hall num'))
    print('%-25s %10d %10s' % ('cell orginal cif', spgnum, '-'))
    print('%-25s %10d %10d' % ('pcell calc', spgnum_pcell, hallnum_pcell))
    print('%-25s %10d %10d' %
          ('ccell calc pcell+std', spgnum_ccell, hallnum_ccell))
    b = True
    if (spgnum != spgnum_pcell):
        b = False
        print('warning: primitive cell... NG')
    if (spgnum != spgnum_ccell):
        b = False
        print('warning: conventional cell... NG')
    if (b == True):
        print('calc... OK')

    return b, spgnum_pcell
コード例 #16
0
 def __standardize(atoms):
     atoms = atoms.copy()
     cell = (atoms.get_cell()).tolist()
     pos = atoms.get_scaled_positions().tolist()
     numbers = atoms.get_atomic_numbers()
     cell, scaled_pos, numbers = spglib.standardize_cell(
         (cell, pos, numbers),
         to_primitive=True,
         symprec=1e-4,
         no_idealize=False,
     )
     atoms = ase.atoms.Atoms(scaled_positions=scaled_pos,
                             numbers=numbers,
                             cell=cell,
                             pbc=True)
     axes = [0, 1, 2]
     lengths = atoms.cell.lengths()
     order = [
         x for x, y in sorted(zip(axes, lengths),
                              key=lambda pair: pair[1])
     ]
     if order != [0, 1, 2]:
         atoms = ase.geometry.permute_axes(atoms, order)
     self.current_stack = atoms
     self.__plot_stack(atoms, fig, ax[2], self.current_scdata)
コード例 #17
0
ファイル: structure.py プロジェクト: scut-ccmp/sagar
 def get_primitive_cell(self, symprec=1e-5):
     spg_cell = (self.lattice, self.positions, self.atoms)
     # 用下面这个原胞会改变坐标轴,no_idealize=True保持了坐标的方向。
     # lattice, positions, atoms = spglib.find_primitive(spg_cell, symprec)
     lattice, positions, atoms = spglib.standardize_cell(spg_cell,
                                                         to_primitive=True,
                                                         no_idealize=True,
                                                         symprec=symprec)
     return self.__class__(lattice, positions, atoms)
コード例 #18
0
ファイル: test_spglib.py プロジェクト: atztogo/spglib
    def test_standardize_cell_from_primitive(self):
        for fname, spgnum in zip(self._filenames, self._spgnum_ref):
            cell = read_vasp(fname)
            if 'distorted' in fname:
                symprec = 1e-1
            else:
                symprec = 1e-5

            prim_cell = standardize_cell(cell,
                                         to_primitive=True,
                                         no_idealize=True,
                                         symprec=symprec)
            std_cell = standardize_cell(prim_cell,
                                        to_primitive=False,
                                        no_idealize=True,
                                        symprec=symprec)
            dataset = get_symmetry_dataset(std_cell, symprec=symprec)
            self.assertEqual(dataset['number'], spgnum,
                             msg=("%s" % fname))
コード例 #19
0
def standardize_cell(structure,
                     symprec,
                     angle_tolerance,
                     to_primitive=False,
                     no_idealize=False):
    """compute the standardised cell for an AiiDA structure

    When computing symmetry, atomic sites with the same **Kind** are treated as
    symmetrically equivalent (rather than just the atomic elements).

    Parameters
    ----------
    structure: aiida.StructureData
    to_primitive: bool
        If True, the standardized primitive cell is created.
    no_idealize: bool
        If True, it is disabled to idealize lengths and angles of
        basis vectors and positions of atoms according to crystal symmetry.
    symprec: float
        Symmetry search tolerance in the unit of length.
    angle_tolerance: float or None
        Symmetry search tolerance in the unit of angle degrees.
        If the value is negative or None, an internally optimized routine
        is used to judge symmetry.

    Returns
    -------
    aiida.StructureData

    """
    from aiida.orm.nodes.data.structure import Site

    structure = convert_structure(structure, "aiida")

    cell, int2kind_map = prepare_for_spglib(structure)

    new_cell = spglib.standardize_cell(
        cell,
        to_primitive=to_primitive,
        no_idealize=no_idealize,
        symprec=symprec,
        angle_tolerance=-1 if angle_tolerance is None else angle_tolerance,
    )
    if new_cell is None:
        raise ValueError("standardization of cell failed")

    new_structure = structure.clone()
    new_structure.clear_sites()
    new_structure.cell = new_cell[0].tolist()
    positions = frac_to_cartesian(new_structure.cell, new_cell[1])
    for position, eid in zip(positions, new_cell[2].tolist()):
        new_structure.append_site(
            Site(kind_name=int2kind_map[eid], position=position))

    return new_structure
コード例 #20
0
ファイル: convert.py プロジェクト: songsr/vaspvis
def convert(bulk, slab, index, output, generate=True, print_M=True):
    primitiveCell = mg.Structure.from_file(bulk)
    refSlab = mg.Structure.from_file(slab)
    sa = SpacegroupAnalyzer(primitiveCell)
    conventionalCell = sa.get_conventional_standard_structure()
    conventionalCell.to(filename='POSCAR.conventional')
    bulk = read('POSCAR.conventional')
    os.remove('POSCAR.conventional')
    slab = surface(bulk, index, layers=2, vacuum=10)
    lattice, _, _ = spglib.standardize_cell(cell=(slab.get_cell(),
                                                  slab.get_scaled_positions(),
                                                  slab.get_atomic_numbers()),
                                            no_idealize=True)
    lattice_params = np.sort(np.linalg.norm(lattice, axis=1))[:2]
    scales = np.round(
        np.array([refSlab.lattice.a, refSlab.lattice.b] / lattice_params), 2)
    newLattice = []
    oldLattice = refSlab.lattice
    for length, scale in zip([oldLattice.a, oldLattice.b], scales):
        for j in range(len(lattice)):
            if abs((np.linalg.norm(lattice[j]) * scale) - length) < 1e-1:
                newLattice.append(copy.copy(scale * lattice[j][:]))
                lattice[j] = [0, 0, 0]
                break
    for i in range(len(lattice)):
        norm = np.linalg.norm(lattice[i])
        if norm > 1e-1:
            newLattice.append(lattice[i] / norm * oldLattice.c)
            break
    newLattice = Lattice(np.array(newLattice))
    for x, y in zip(oldLattice.angles, newLattice.angles):
        assert abs(
            x - y
        ) < 1e-2, "The converted lattice has incorrect angles: {} compared with reference slab: {}".format(
            " ".join(str(x) for x in newLattice.angles),
            " ".join(str(x) for x in oldLattice.angles))
    newSlab = Structure(newLattice, [], [])
    for atom in refSlab:
        newSlab.append(atom.specie, atom.frac_coords[:])

    if generate:
        Poscar(newSlab.get_sorted_structure()).write_file(output, direct=True)

    transformMat = newSlab.lattice.matrix.dot(
        np.linalg.inv(primitiveCell.lattice.matrix))
    transformMat = transformMat.round().astype(int)
    if print_M:
        print('-------------------------------------------')
        print('Your Transformtaion Matrix is:')
        print(' ')
        print(transformMat)
        print('-------------------------------------------')

    return transformMat
コード例 #21
0
    def standardize(self,
                    to_primitive=True,
                    symprec=1e-4,
                    angle_tolerance=5) -> None:
        """Wrapper of the spglib standardize() function with extra features.

        For 2D systems, the non-periodic axis is enforced as the z-axis.

        Args:
            to_primitive (bool): If True, primitive cell is obtained. If False, conventional cell is obtained.
            symprec (float): Precision to determine new cell.

        Note:
            The combination of to_primitive=True and a larger value of symprec (1e-2) can be used to refine a structure.
        """

        atoms = self.copy()
        pbc1 = find_periodic_axes(atoms)
        lattice, positions, numbers = (
            atoms.get_cell(),
            atoms.get_scaled_positions(),
            atoms.numbers,
        )
        cell = (lattice, positions, numbers)
        newcell = spglib.standardize_cell(
            cell,
            to_primitive=to_primitive,
            no_idealize=False,
            symprec=symprec,
            angle_tolerance=angle_tolerance,
        )
        if newcell == None:
            logger.error("Cell could not be standardized.")
            return None
        else:
            atoms = ase.Atoms(
                scaled_positions=newcell[1],
                numbers=newcell[2],
                cell=newcell[0],
                pbc=atoms.pbc,
            )
            pbc2 = find_periodic_axes(atoms)
            logger.debug("new pbc: {} {} {}".format(*pbc2))
            if pbc1 != pbc2:
                old = [k for k, v in pbc1.items() if v]
                new = [k for k, v in pbc2.items() if v]
                assert len(old) == len(
                    new), "Periodicity changed due to standardization."
                if len(new) == 2:
                    npbcax = list(set([0, 1, 2]) - set(new))[0]
                    atoms = ase.geometry.permute_axes(atoms, new + [npbcax])

            self.__init__(atoms)
コード例 #22
0
    def get_refined_pcell(self):
        """
        Using spglib's standardize_cell method to
        refine the cell of giving.
        If self is a non-primitive cell, the number of
        atoms will reduced.
        else will return a refined primitive cell.
        """
        rcell = (self.lattice, self.positions, self.numbers)
        lattice, positions, numbers = spglib.standardize_cell(
            rcell, to_primitive=True, no_idealize=False, symprec=self.symprec)

        return self.__class__(lattice, positions, numbers)
コード例 #23
0
ファイル: f34.py プロジェクト: tilde-lab/aiida-crystal-dft
    def __str__(self):
        # check for ECPs in basis family
        has_ecp = []
        if self.basis and not self.basis.predefined:
            composition = set(self.atomic_numbers)
            has_ecp = [num for num in composition if not self.basis.get_basis(chemical_symbols[num]).all_electron]

        # convert geometry to primitive and find inequivalent atoms
        cell = self.abc, self.positions, self.atomic_numbers
        cell = spglib.standardize_cell(cell, to_primitive=True, no_idealize=False)
        abc, positions, atomic_numbers = cell

        # symmetries related stuff
        dataset = spglib.get_symmetry_dataset(cell)

        # leave only symmetrically inequivalent atoms
        inequiv_atoms = np.unique(dataset['equivalent_atoms'])
        positions = positions[inequiv_atoms]
        atomic_numbers = atomic_numbers[inequiv_atoms]

        # convert positions from fractional to cartesian
        positions = np.dot(abc.T, positions.T).T

        # convert symmetry operations from fractional to cartesian
        rotations = np.dot(abc.T, np.dot(dataset["rotations"], np.linalg.inv(abc.T)))
        rotations = np.swapaxes(rotations, 0, 1)
        translations = np.dot(dataset["translations"], abc)
        n_symops = len(dataset["translations"])
        symops = np.zeros((n_symops * 4, 3), dtype=float)
        symops[0::4] = rotations[:, 0]
        symops[1::4] = rotations[:, 1]
        symops[2::4] = rotations[:, 2]
        symops[3::4] = translations

        # make a list of lines
        f34_lines = ["{0} {1} {2}".format(self.dimensionality,
                                          self.centring,
                                          self.crystal_type)]
        f34_lines += ["{0[0]:17.9E} {0[1]:17.9E} {0[2]:17.9E}".format(
            np.round(vec, 9) + 0.) for vec in abc]

        # symmetry operation part
        f34_lines.append(str(n_symops))
        f34_lines += ["{0[0]:17.9E} {0[1]:17.9E} {0[2]:17.9E}".format(
            np.round(line, 9) + 0.) for line in symops]
        # atoms part
        f34_lines.append(str(len(atomic_numbers)))
        f34_lines += ["{0:3} {1[0]:17.9E} {1[1]:17.9E} {1[2]:17.9E}".format(
            anum + 200 if anum in has_ecp else anum, pos) for anum, pos in zip(atomic_numbers, positions)]

        return "\n".join(f34_lines)
コード例 #24
0
    def get_shaped_cell(self):
        """
        The numbers of atoms is not changed, but the lattice shape
        is optimized to be fulled.
        """
        n = self.numbers.size
        numbers = self.numbers.copy()
        index = np.array([i for i in range(n)])
        rcell = (self.lattice, self.positions, index)
        lattice, positions, new_index = spglib.standardize_cell(
            rcell, to_primitive=True, no_idealize=False, symprec=self.symprec)

        numbers = numbers[new_index]
        return self.__class__(lattice, positions, numbers)
コード例 #25
0
ファイル: xyz.py プロジェクト: yingli2009/ASAP
 def standardize(self, sbs=[], symprec=1e-2):
     """
     reduce to primitive cell
     """
     import spglib
     if len(sbs) == 0:
         sbs = range(self.nframes)
     for i in sbs:
         frame = self.frames[i]
         lattice, scaled_positions, numbers = spglib.standardize_cell(
             frame, to_primitive=1, no_idealize=1, symprec=symprec)
         self.frames[i] = Atoms(numbers=numbers,
                                cell=lattice,
                                scaled_positions=scaled_positions,
                                pbc=frame.get_pbc())
コード例 #26
0
def gulp_opt(stru):
    gulp_inp = 'opt.gin'
    tp_inp = 'tp_inp'
    out = 'out'
    cif_out = 'final.cif'
    symprec = 0.01

    ccell = standardize_cell((stru.cell, stru.get_scaled_positions(), stru.numbers), symprec=symprec)
    if ccell:
        symmetry = get_symmetry(ccell, symprec=symprec)
        spacegroup = get_spacegroup(ccell, symprec=symprec)
    else:
        symmetry = get_symmetry((stru.cell, stru.get_scaled_positions(), stru.numbers), symprec=symprec)
        spacegroup = get_spacegroup((stru.cell, stru.get_scaled_positions(), stru.numbers), symprec=symprec)
    asymmetric_atoms = np.unique(symmetry.equivalent_atoms)
    pass
コード例 #27
0
ファイル: standardize.py プロジェクト: kei0822kei/twinpy
    def get_standardized_cell(self,
                              to_primitive: bool,
                              no_idealize: bool,
                              symprec: float = 1e-5,
                              no_sort: bool = False,
                              get_sort_list: list = False):
        """
        Get stadandardized cell.

        Args:
            to_primitive (bool): True => primitive,
                                 False => conventional.
            no_idealize (bool): True => not rotate crystal body,
                                False => rotate crystal body
            symprec (float): symmetry tolerance, for more detail
                             see spglib documentation
            no_sort (bool): does not change atoms order
            get_sort_list (bool): When no_sort=True, return sort list

        Returns:
            tuple: If get_sort_list=False, return cell.
                   If get_sort_list=True, return (cell, sort_list).
        """
        spg_cell = spglib.standardize_cell(self._cell_for_spglib,
                                           to_primitive=to_primitive,
                                           no_idealize=no_idealize,
                                           symprec=symprec)
        symbols = get_symbols_from_numbers(spg_cell[2])
        std_cell = (spg_cell[0], spg_cell[1], symbols)

        if no_sort:
            return std_cell

        num_atoms, unique_symbols, scaled_positions, sort_list = \
            sort_positions_by_symbols(
                    symbols=std_cell[2],
                    positions=std_cell[1])
        symbols = []
        for num, symbol in zip(num_atoms, unique_symbols):
            symbols.extend([symbol] * num)

        sort_std_cell = (std_cell[0], scaled_positions, symbols)

        if get_sort_list:
            return (sort_std_cell, sort_list)

        return sort_std_cell
コード例 #28
0
    def get_primitive_atoms(self, atoms):
        """Transform from primitive to conventional cell"""

        lattice, scaled_positions, numbers = standardize_cell(atoms,
                                                              to_primitive=True,
                                                              no_idealize=False,
                                                              symprec=1e-5)

        atoms = Atoms(numbers=numbers,
                      cell=lattice,
                      pbc=True)

        atoms.set_scaled_positions(scaled_positions)

        atoms.wrap()

        return atoms
コード例 #29
0
    def standardize(self, to_primitive=True, symprec=1e-4):
        """ Wrapper of the spglib standardize() function with extra features.

        For 2D systems, the non-periodic axis is enforced as the z-axis.
        
        Args:
            to_primitive (bool): Reduces to primitive cell or not.
            symprec (float): Precision to determine new cell.

        Note:
            The combination of to_primitive=True and a larger value of symprec (1e-3) can be used to symmetrize a structure.
        """
        atoms = self.atoms.copy()
        pbc1 = self.find_nonperiodic_axes()
        lattice, positions, numbers = (
            atoms.get_cell(),
            atoms.get_scaled_positions(),
            atoms.numbers,
        )
        cell = (lattice, positions, numbers)
        newcell = spglib.standardize_cell(cell,
                                          to_primitive=to_primitive,
                                          no_idealize=False,
                                          symprec=symprec)
        if newcell == None:
            logging.error("Cell could not be standardized.")
            return None
        else:
            atoms = ase.Atoms(
                scaled_positions=newcell[1],
                numbers=newcell[2],
                cell=newcell[0],
                pbc=self.atoms.pbc,
            )
            pbc2 = self.find_nonperiodic_axes()
            if pbc1 != pbc2:
                old = [k for k, v in pbc1.items() if v]
                new = [k for k, v in pbc2.items() if v]
                assert len(old) == len(
                    new), "Periodicity changed due to standardization."
                if len(new) == 2:
                    npbcax = list(set([0, 1, 2]) - set(new))[0]
                    atoms = ase.geometry.permute_axes(atoms, new + [npbcax])
                    assert self.is_2d(atoms), "Permutation to 2D not working."
            self.atoms = atoms
コード例 #30
0
ファイル: f34.py プロジェクト: tilde-lab/aiida-crystal-dft
    def read(self, file):
        """Read and parse fort.34 file"""
        if isinstance(file, str):
            with open(file) as f:
                data = f.read()
        else:
            data = file.read()
        parsed_data = _parse_string(f34_parser(), data)
        self.dimensionality, self.centring, self.crystal_type = parsed_data['header']
        if self.dimensionality != 3:
            raise NotImplementedError('Structure with dimensionality < 3 currently not supported')

        # primitive cell vectors and basis positions in cartesian coordinates
        abc = np.array(parsed_data['abc'].asList()).reshape((3, 3))
        positions = np.array([d[1:] for d in parsed_data['geometry']])

        # convert positions to fractional
        positions = np.dot(np.linalg.inv(abc).T, positions.T).T
        atomic_numbers = [d[0] for d in parsed_data['geometry']]

        # convert to conventional cell
        cell = (abc, positions, atomic_numbers)
        cell = spglib.standardize_cell(cell, to_primitive=False, no_idealize=False)
        self.abc, self.positions, atomic_numbers = cell

        # ECPs
        self.atomic_numbers = [num if num < 201 else num - 200 for num in atomic_numbers]

        # get symmetry operations
        self.n_symops = parsed_data['n_symops']
        self.symops = np.array(parsed_data['symops'].asList()).reshape(self.n_symops * 4, 3)
        rotations = np.zeros((self.n_symops, 3, 3))
        for i in range(3):
            rotations[:, i] = self.symops[i::4]

        # convert symmetry operations from cartesian to fractional
        rotations = np.dot(np.dot(np.linalg.inv(abc.T), rotations), abc.T)

        # have to round rotations matrix as it is used to find symmetry group
        rotations = np.round(np.swapaxes(rotations, 0, 1), 9)
        translations = np.dot(self.symops[3::4], np.linalg.inv(abc))
        hall = spglib.get_hall_number_from_symmetry(rotations, translations)
        self.space_group = int(spglib.get_spacegroup_type(hall)['number'])
        # we have conventional cell now
        return self
コード例 #31
0
    def _reduce_to_primitive(self, structure):
        """Reduce the two structure to their primitive type"""
        try:
            import spglib
        except ImportError:
            raise SpgLibNotFoundError(
                "SpgLib is required if to_primitive=True")
        cell = (structure.get_cell()).tolist()
        pos = structure.get_scaled_positions().tolist()
        numbers = structure.get_atomic_numbers()

        cell, scaled_pos, numbers = spglib.standardize_cell(
            (cell, pos, numbers), to_primitive=True)

        atoms = Atoms(scaled_positions=scaled_pos,
                      numbers=numbers,
                      cell=cell,
                      pbc=True)
        return atoms
コード例 #32
0
ファイル: test_spglib.py プロジェクト: atztogo/spglib
    def test_standardize_cell_and_pointgroup(self):
        for fname, spgnum in zip(self._filenames, self._spgnum_ref):
            cell = read_vasp(fname)
            if 'distorted' in fname:
                symprec = 1e-1
            else:
                symprec = 1e-5

            std_cell = standardize_cell(cell,
                                        to_primitive=False,
                                        no_idealize=True,
                                        symprec=symprec)
            dataset = get_symmetry_dataset(std_cell, symprec=symprec)
            self.assertEqual(dataset['number'], spgnum,
                             msg=("%s" % fname))

            # The test for point group has to be done after standarization.
            ptg_symbol, _, _ = get_pointgroup(dataset['rotations'])
            self.assertEqual(dataset['pointgroup'],
                             ptg_symbol,
                             msg=("%s" % fname))
コード例 #33
0
ファイル: example.py プロジェクト: atztogo/spglib
print(" Refine distorted rutile structure")
lattice, positions, numbers = spglib.refine_cell(rutile_dist, symprec=1e-1)
show_cell(lattice, positions, numbers)
print('')

print("[find_primitive]")
print(" Fine primitive distorted silicon structure")
lattice, positions, numbers = spglib.find_primitive(silicon_dist, symprec=1e-1)
show_cell(lattice, positions, numbers)
print('')

print("[standardize_cell]")
print(" Standardize distorted rutile structure:")
print(" (to_primitive=0 and no_idealize=0)")
lattice, positions, numbers = spglib.standardize_cell(rutile_dist,
                                                      to_primitive=0,
                                                      no_idealize=0,
                                                      symprec=1e-1)
show_cell(lattice, positions, numbers)
print('')

print("[standardize_cell]")
print(" Standardize distorted rutile structure:")
print(" (to_primitive=0 and no_idealize=1)")
lattice, positions, numbers = spglib.standardize_cell(rutile_dist,
                                                      to_primitive=0,
                                                      no_idealize=1,
                                                      symprec=1e-1)
show_cell(lattice, positions, numbers)
print('')

print("[standardize_cell]")
コード例 #34
0
def crystal_space_group(system, symprec=1e-5, to_primitive=False,
                        no_idealize=False):
    """
    Uses spglib to evaluate space group information for a given system.
    
    Parameters
    ----------
    system : atomman.System
        The system to analyze.
    symprec : float
        Absolute length tolerance to use in identifying symmetry of atomic
        sites and system boundaries.
    to_primitive : bool
        Indicates if the returned unit cell is conventional (False) or
        primitive (True). Default value is False.
    no_idealize : bool
        Indicates if the atom positions in the returned unit cell are averaged
        (True) or idealized based on the structure (False).  Default value is
        False.
    
    Returns
    -------
    dict
        Results dictionary containing space group information and an associated
        unit cell system.
    """
    # Identify the standardized unit cell representation
    ucell = spglib.standardize_cell(system.dump('spglib_cell'),
                                    to_primitive=to_primitive,
                                    no_idealize=no_idealize, symprec=symprec)
    
    # Convert back to atomman systems and normalize
    ucell = am.load('spglib_cell', ucell, symbols=system.symbols)
    ucell.atoms.pos -= ucell.atoms.pos[0]
    ucell = ucell.normalize()
    
    # Get space group metadata
    sym_data = spglib.get_symmetry_dataset(ucell.dump('spglib_cell'))
    spg_type = spglib.get_spacegroup_type(sym_data['hall_number'])
    
    # Generate Pearson symbol
    if spg_type['number'] <= 2:
        crystalclass = 'a'
    elif spg_type['number'] <= 15:
        crystalclass = 'm'
    elif spg_type['number'] <= 74:
        crystalclass = 'o'
    elif spg_type['number'] <= 142:
        crystalclass = 't'
    elif spg_type['number'] <= 194:
        crystalclass = 'h'
    else:
        crystalclass = 'c'
    
    latticetype = spg_type['international'][0]
    if latticetype in ['A', 'B']:
        latticetype = 'C'
    
    natoms = str(ucell.natoms)
    pearson = crystalclass + latticetype + natoms
    
    # Return results
    results_dict = spg_type
    results_dict['ucell'] = ucell
    results_dict['hall_number'] = sym_data['hall_number']
    results_dict['wyckoffs'] = sym_data['wyckoffs']
    results_dict['pearson'] = pearson
    
    return results_dict