Beispiel #1
0
def get_sym(cell, symprec=1e-5, print_atom=False, print_analysis=True):
    '''Giving a cell, return symmetry analysis'''

    # spglib only work with tuple
    cell = tuple(cell)

    #Space group info
    spg_label, spg_number = spglib.get_spacegroup(cell, symprec).split(' ')
    spg_number = spg_number.split("(")[1].split(")")[0]
    Schoenflies_label = spglib.get_spacegroup(cell, symprec,
                                              symbol_type=1).split(' ')[0]
    sym = spglib.get_symmetry(cell, symprec)
    rotations = sym['rotations']
    translations = sym['translations']
    equi_atoms = sym['equivalent_atoms']

    is_std = is_prim = False
    std_cell = spglib.refine_cell(cell, symprec)
    prim_cell = spglib.find_primitive(cell, symprec)
    if compare_cells(cell, std_cell): is_std = True
    if compare_cells(cell, prim_cell): is_prim = True

    atoms = utils.convert_atomtype(cell[2])
    if print_analysis == True:
        #Cell info
        std_cell = spglib.refine_cell(cell, symprec)
        prim_cell = spglib.find_primitive(cell, symprec)

        #Print
        misc.print_msg("Spacegroup  number           : %s" % (spg_number))
        misc.print_msg("Short International symbol   : %s" % (spg_label))
        misc.print_msg("Schoenflies symbol           : %s" %
                       (Schoenflies_label))
        if print_atom == True:
            misc.print_msg("Atoms list (No. - Sym - Symbol):")
            for i, atom in enumerate(atoms):
                misc.print_msg("%3d   %3d   %s" %
                               (i + 1, equi_atoms[i] + 1, atom))
            misc.print_msg("Irreducible atoms:")
            for i, index in enumerate(np.unique(equi_atoms)):
                coord = cell[1][index]
                misc.print_msg(
                    "%3d  %3s    %7f5 %7f5 %7f5" %
                    (i + 1, atoms[index], coord[0], coord[1], coord[2]))
        misc.print_msg("Number of irreducible atoms  : %d" %
                       (np.unique(equi_atoms).shape[0]))
        misc.print_msg("Standard cell                : %r" % (is_std))
        misc.print_msg("Primitive cell               : %r" % (is_prim))
    else:
        # Return an standard cell object with irreducible atoms
        irred_idx = np.unique(equi_atoms)
        lattice = cell[0]
        irred_coord = cell[1][irred_idx, :]
        irred_label = np.array(cell[2])[irred_idx]
        irred_cell = (lattice, irred_coord, irred_label)

        return irred_cell, int(spg_number), spg_label, rotations, translations
Beispiel #2
0
def check_symmetry(phonon, optional_structure_info):
    # Assumed that primitive cell is the cell that user is interested in.
    print(_get_symmetry_yaml(phonon.primitive,
                             phonon.primitive_symmetry,
                             phonon.version))

    if phonon.unitcell.magnetic_moments is None:
        base_fname = get_default_cell_filename(phonon.calculator)
        symprec = phonon.primitive_symmetry.get_symmetry_tolerance()
        (bravais_lattice,
         bravais_pos,
         bravais_numbers) = spglib.refine_cell(phonon.primitive, symprec)
        bravais = PhonopyAtoms(numbers=bravais_numbers,
                               scaled_positions=bravais_pos,
                               cell=bravais_lattice)
        filename = 'B' + base_fname
        print("# Symmetrized conventional unit cell is written into %s."
              % filename)
        trans_mat = guess_primitive_matrix(bravais, symprec=symprec)
        primitive = get_primitive(bravais, trans_mat, symprec=symprec)
        write_crystal_structure(
            filename,
            bravais,
            interface_mode=phonon.calculator,
            optional_structure_info=optional_structure_info)

        filename = 'P' + base_fname
        print("# Symmetrized primitive is written into %s." % filename)
        write_crystal_structure(
            filename,
            primitive,
            interface_mode=phonon.calculator,
            optional_structure_info=optional_structure_info)
Beispiel #3
0
def refine(ase_obj, accuracy=1E-03):
    """
    Refine ASE structure using spglib

    Args:
        ase_obj: (object) ASE structure
        accuracy: (float) spglib tolerance, normally within [1E-02, 1E-04]

    Returns:
        Refined ASE structure (object) *or* None
        None *or* error (str)
    """
    try:
        symmetry = spglib.get_spacegroup(ase_obj, symprec=accuracy)
        lattice, positions, numbers = spglib.refine_cell(ase_obj,
                                                         symprec=accuracy)
    except:
        return None, 'Error while structure refinement'

    try:
        spacegroup = int(symmetry.split()[1].replace("(", "").replace(")", ""))
    except (ValueError, IndexError):
        return None, 'Symmetry error (coinciding atoms?) in structure'

    try:
        return crystal(Atoms(numbers=numbers,
                             cell=lattice,
                             scaled_positions=positions,
                             pbc=True),
                       spacegroup=spacegroup,
                       primitive_cell=True,
                       onduplicates='replace'), None
    except:
        return None, 'Unrecognized sites or invalid site symmetry in structure'
Beispiel #4
0
    def refine_cell(self, symprec=1e-5):
        """
        Refine a pychemia Structure using the tolerances and return a new structure in a Bravais lattice

        :param symprec: (float) Tolerance of distance between atomic positions and between lengths of lattice vectors
                        to be tolerated in the symmetry finding.
        :return: A new pychemia Structure in a Bravais lattice

        :rtype : (pychemia.Structure)

        Example:
        >>> import pychemia
        >>> a = 4.05
        >>> b = a/2
        >>> fcc = pychemia.Structure(symbols=['Au'],
        ...       cell=[[0, b+1E-5, b-1E-5], [b+1E-5, 0, b-1E-5], [b+1E-5, b-1E-5, 0]], periodicity=True)
        >>> symm = pychemia.crystal.CrystalSymmetry(fcc)
        >>> symm.number()
        2
        >>> symm.symbol() == u'P-1'
        True
        >>> fcc2 = symm.refine_cell(symprec=1E-3)
        >>> symm2 = pychemia.crystal.CrystalSymmetry(fcc2)
        >>> symm2.number()
        225
        >>> symm2.symbol() == u'Fm-3m'
        True

        """
        new_spglib_cell = spg.refine_cell(self.spglib_cell, symprec=symprec)
        return self.get_new_structure(new_spglib_cell)
Beispiel #5
0
    def refine_cell(self, symprec=1e-5):
        """
        Refine a pychemia Structure using the tolerances and return a new structure in a Bravais lattice

        :param symprec: (float) Tolerance of distance between atomic positions and between lengths of lattice vectors
                        to be tolerated in the symmetry finding.
        :return: A new pychemia Structure in a Bravais lattice

        :rtype : (pychemia.Structure)

        Example:
        >>> import pychemia
        >>> a = 4.05
        >>> b = a/2
        >>> fcc = pychemia.Structure(symbols=['Au'],
        ...       cell=[[0, b+1E-5, b-1E-5], [b+1E-5, 0, b-1E-5], [b+1E-5, b-1E-5, 0]], periodicity=True)
        >>> symm = pychemia.crystal.CrystalSymmetry(fcc)
        >>> symm.number()
        2
        >>> symm.symbol() == u'P-1'
        True
        >>> fcc2 = symm.refine_cell(symprec=1E-3)
        >>> symm2 = pychemia.crystal.CrystalSymmetry(fcc2)
        >>> symm2.number()
        225
        >>> symm2.symbol() == u'Fm-3m'
        True

        """
        new_spglib_cell = spg.refine_cell(self.spglib_cell, symprec=symprec)
        return self.get_new_structure(new_spglib_cell)
Beispiel #6
0
def cell_to_std(cell, symprec=1e-5):
    std_cell = spglib.refine_cell(cell, symprec)
    if compare_cells(cell, std_cell):
        print('Unit cell is already a standard cell. Nothing changes')
        return cell
    else:
        print('Unit cell was transformed to a standard cell')
        return std_cell
Beispiel #7
0
def get_sym(cell, symprec=1e-5, print_atom=False, export_operator=False):

    #Space group info
    intl_label, number = spglib.get_spacegroup(cell, symprec).split(' ')
    number = number.split("(")[1].split(")")[0]
    Schoenflies_label = spglib.get_spacegroup(cell, symprec,
                                              symbol_type=1).split(' ')[0]
    sym = spglib.get_symmetry(cell, symprec)
    rotations = sym['rotations']
    translations = sym['translations']
    equi_atoms = sym['equivalent_atoms']

    is_std = is_prim = False
    std_cell = spglib.refine_cell(cell, symprec)
    prim_cell = spglib.find_primitive(cell, symprec)
    if compare_cells(cell, std_cell): is_std = True
    if compare_cells(cell, prim_cell): is_prim = True

    atoms = utils.convert_atomtype(cell[2])
    if export_operator == False:
        #Cell info
        std_cell = spglib.refine_cell(cell, symprec)
        prim_cell = spglib.find_primitive(cell, symprec)
        #Print
        misc.print_msg("Spacegroup  number           : %s" % (number))
        misc.print_msg("Short International symbol   : %s" % (intl_label))
        misc.print_msg("Schoenflies symbol           : %s" %
                       (Schoenflies_label))
        if print_atom == True:
            misc.print_msg("Atoms list (No. - Sym - Symbol):")
            for i, atom in enumerate(atoms):
                misc.print_msg("%3d   %3d   %s" %
                               (i + 1, equi_atoms[i] + 1, atom))
            misc.print_msg("Irreducible atoms:")
            for i, index in enumerate(np.unique(equi_atoms)):
                misc.print_msg("%3d  %3s    %7f5 %7f5 %7f5" %
                               (i + 1, atoms[index], cell[1][index][0],
                                cell[1][index][1], cell[1][index][2]))
        misc.print_msg("Number of irreducible atoms  : %d" %
                       (np.unique(equi_atoms).shape[0]))
        misc.print_msg("Standard cell                : %r" % (is_std))
        misc.print_msg("Primitive cell               : %r" % (is_prim))
        return is_std, is_prim
    else:
        return (number, intl_label), equi_atoms, rotations, translations
Beispiel #8
0
    def find_conventional_cell(self, symprec = 1e-5):
        """
        Find the conventional cell of the structure.

        Returns:
            Conventional cell as a Structure object.
        """
        t = spglib.refine_cell(self.as_tuple(), symprec = symprec)
        return Structure(*t)
Beispiel #9
0
 def refine_cell(self, tilde_obj):
     '''
     NB only used for perovskite_tilting app
     '''
     try: lattice, positions, numbers = spg.refine_cell(tilde_obj['structures'][-1], symprec=self.accuracy, angle_tolerance=self.angle_tolerance)
     except Exception as ex:
         self.error = 'Symmetry finder error: %s' % ex
     else:
         self.refinedcell = Atoms(numbers=numbers, cell=lattice, scaled_positions=positions, pbc=tilde_obj['structures'][-1].get_pbc())
         self.refinedcell.periodicity = sum(self.refinedcell.get_pbc())
         self.refinedcell.dims = abs(det(tilde_obj['structures'][-1].cell))
Beispiel #10
0
def cell_to_std(cell, symprec=1e-5):
    '''Convert a cell to a standard cell'''

    # spglib only work with tuple
    cell = tuple(cell)

    std_cell = spglib.refine_cell(cell, symprec)
    if compare_cells(cell, std_cell):
        print('Unit cell is already a standard cell. Nothing changes')
        return cell
    else:
        print('Unit cell was transformed to a standard cell')
        return std_cell
Beispiel #11
0
def get_crystallographic_cell(cell, tolerance=1e-5):
    numbers = cell.numbers
    (std_lattice,
     std_positions,
     std_numbers) = spglib.refine_cell(
         (cell.lattice.T, cell.get_points().T, numbers),
         symprec=tolerance)
    masses = cell.get_masses()
    std_masses = _transfer_masses_by_numbers(std_numbers, numbers, masses)
    return Cell(lattice=std_lattice.T,
                points=std_positions.T,
                numbers=std_numbers,
                masses=std_masses)
Beispiel #12
0
    def refine_cell(self,
                    symprec: float = 1e-5,
                    angle_tolerance: float = -1) -> Union[Stru, None]:
        """Standardized crystal structure following space group type

        :params symprec: distance tolerance in Cartesian coordinates to find crystal symmetry. Default: 1e-5
        :params angle_tolerance: tolerance of angle between basis vectors in degrees to be tolerated in the symmetry finding. Default: -1
        :return lattice, atomic scaled positions, and atomic numbersthat are symmetrized following space group type
        """

        import spglib
        newcell = spglib.refine_cell(self.spgcell, symprec, angle_tolerance)

        return self.modified_stru(newcell)
Beispiel #13
0
def writeCIF(cell, prec, basename):

    # Find spacegroup name and number
    sg = spglib.get_spacegroup(cell, symprec=prec)
    sg, sgid = sg.split(' (')
    sgid = sgid.replace(')', '')

    # Find detailed info about the refined cell
    lattice, scaled_positions, numbers = spglib.refine_cell(cell, prec)
    if len(numbers) != len(cell):
        # create new cell
        ncell = (lattice, scaled_positions, numbers)
    else:
        ncell = copy.deepcopy(cell)
    sym = spglib.get_symmetry(ncell, prec)
    uniques = np.unique(sym['equivalent_atoms'])
    a, b, c, alpha, beta, gamma = cellParameters(lattice)

    f = open((basename + '_' + sgid + '.cif').replace('/', '|'), 'w')

    f.write(f'# Symmetrized structure with precision = {prec}\n')

    f.write(f'data_{basename}{sg}\n'.replace(' ', '_'))
    f.write('_cell_length_a                  %.7g\n' % a)
    f.write('_cell_length_b                  %.7g\n' % b)
    f.write('_cell_length_c                  %.7g\n' % c)
    f.write('_cell_angle_alpha               %.7g\n' % alpha)
    f.write('_cell_angle_beta                %.7g\n' % beta)
    f.write('_cell_angle_gamma               %.7g\n' % gamma)
    f.write("_symmetry_space_group_name_H-M  '" + sg + "'\n")
    f.write('_symmetry_Int_Tables_number     ' + str(sgid) + '\n')

    # Write out atomic positions
    f.write('''
loop_
_atom_site_label
_atom_site_type_symbol
_atom_site_occupancy
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
''')

    for pos, at in zip(scaled_positions[uniques], numbers[uniques]):
        sym = element_symbols[at]
        f.write('%s %s 1.0 %.7f %.7f %.7f\n' %
                (sym, sym, pos[0], pos[1], pos[2]))

    f.close()
Beispiel #14
0
def writeCIF(cell, prec, basename):

    # Find spacegroup name and number
    sg = spglib.get_spacegroup(cell, symprec=prec)
    sg, sgid = sg.split(' (')
    sgid = sgid.replace(')', '')

    # Find detailed info about the refined cell
    lattice, scaled_positions, numbers = spglib.refine_cell(cell, prec)
    if len(numbers) != len(cell):
        # create new cell
        ncell = (lattice, scaled_positions, numbers)
    else:
        ncell = copy.deepcopy(cell)
    sym = spglib.get_symmetry(ncell, prec)
    uniques = np.unique(sym['equivalent_atoms'])
    a, b, c, alpha, beta, gamma = cellParameters(lattice)

    f = open((basename + '_' + sgid + '.cif').replace('/', '|'), 'w')

    f.write(f'# Symmetrized structure with precision = {prec}\n')

    f.write(f'data_{basename}{sg}\n'.replace(' ', '_'))
    f.write('_cell_length_a                  %.7g\n' % a)
    f.write('_cell_length_b                  %.7g\n' % b)
    f.write('_cell_length_c                  %.7g\n' % c)
    f.write('_cell_angle_alpha               %.7g\n' % alpha)
    f.write('_cell_angle_beta                %.7g\n' % beta)
    f.write('_cell_angle_gamma               %.7g\n' % gamma)
    f.write("_symmetry_space_group_name_H-M  '" + sg + "'\n")
    f.write('_symmetry_Int_Tables_number     ' + str(sgid) + '\n')

    # Write out atomic positions
    f.write('''
loop_
_atom_site_label
_atom_site_type_symbol
_atom_site_occupancy
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
''')

    for pos, at in zip(scaled_positions[uniques], numbers[uniques]):
        sym = element_symbols[at]
        f.write('%s %s 1.0 %.7f %.7f %.7f\n' % (sym, sym, pos[0], pos[1], pos[2]))

    f.close()
Beispiel #15
0
def writeCIF (cell, prec, basename):

  # Find spacegroup name and number
  sg = spglib.get_spacegroup(cell, symprec=prec)
  sg, sgid = sg.split(" (")
  sgid = sgid.replace(")", "")

  # Find detailed info about the refined cell
  lattice, scaled_positions, numbers = spglib.refine_cell (cell, prec)
  if len(numbers)!=len(cell):
    #create new cell
    ncell = (lattice, scaled_positions, numbers)
  else:
    ncell = copy.deepcopy(cell)
  sym = spglib.get_symmetry(ncell, prec)
  uniques = np.unique(sym['equivalent_atoms'])
  a, b, c, alpha, beta, gamma = cellParameters (lattice)

  f = open((basename + "_" + sgid + ".cif").replace("/","|"), "w")

  f.write ("# Symmetrized structure with precision = %g\n" % prec)

  f.write (("data_" + basename + sg + "\n").replace(" ", "_"))
  f.write ("_cell_length_a        %.7g\n" % a)
  f.write ("_cell_length_b        %.7g\n" % b)
  f.write ("_cell_length_c        %.7g\n" % c)
  f.write ("_cell_angle_alpha     %.7g\n" % alpha)
  f.write ("_cell_angle_beta      %.7g\n" % beta)
  f.write ("_cell_angle_gamma     %.7g\n" % gamma)
  f.write ("_symmetry_space_group_name_H-M   '" + sg + "'\n")
  f.write ("_symmetry_Int_Tables_number      " + str(sgid) + "\n")

  # Write out atomic positions
  f.write ("""
loop_
_atom_site_label
_atom_site_type_symbol
_atom_site_occupancy
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
""")

  for pos, at in zip(scaled_positions[uniques], numbers[uniques]):
    sym = element_symbols[at]
    f.write ("%s %s 1.0 %.7f %.7f %.7f\n" % (sym, sym, pos[0], pos[1], pos[2]))

  f.close()
Beispiel #16
0
    def get_refined_structure(self):
        """
        Get the refined structure based on detected symmetry. The refined
        structure is a *conventional* cell setting with atoms moved to the
        expected symmetry positions.

        Returns:
            Refined structure.
        """
        # Atomic positions have to be specified by scaled positions for spglib.
        lattice, scaled_positions, numbers \
            = spglib.refine_cell(self._cell, self._symprec, self._angle_tol)

        species = [self._unique_species[i - 1] for i in numbers]
        s = Structure(lattice, species, scaled_positions)
        return s.get_sorted_structure()
Beispiel #17
0
    def get_refined_structure(self):
        """
        Get the refined structure based on detected symmetry. The refined
        structure is a *conventional* cell setting with atoms moved to the
        expected symmetry positions.

        Returns:
            Refined structure.
        """
        # Atomic positions have to be specified by scaled positions for spglib.
        lattice, scaled_positions, numbers \
            = spglib.refine_cell(self._cell, self._symprec, self._angle_tol)

        species = [self._unique_species[i - 1] for i in numbers]
        s = Structure(lattice, species, scaled_positions)
        return s.get_sorted_structure()
Beispiel #18
0
 def refine_cell(self, tilde_obj):
     '''
     NB only used for perovskite_tilting app
     '''
     try:
         lattice, positions, numbers = spg.refine_cell(
             tilde_obj['structures'][-1],
             symprec=self.accuracy,
             angle_tolerance=self.angle_tolerance)
     except Exception as ex:
         self.error = 'Symmetry finder error: %s' % ex
     else:
         self.refinedcell = Atoms(numbers=numbers,
                                  cell=lattice,
                                  scaled_positions=positions,
                                  pbc=tilde_obj['structures'][-1].get_pbc())
         self.refinedcell.periodicity = sum(self.refinedcell.get_pbc())
         self.refinedcell.dims = abs(det(tilde_obj['structures'][-1].cell))
Beispiel #19
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f',
                        '--file',
                        default='POSCAR',
                        type=str,
                        help='path to input file')
    parser.add_argument('-t',
                        '--tol',
                        default=1e-3,
                        type=float,
                        help='symmetry tolerance (default 1e-3)')
    parser.add_argument('-o',
                        '--output',
                        default='poscar',
                        help='output file format')
    args = parser.parse_args()

    struct = Structure.from_file(args.file)
    sym = SpacegroupAnalyzer(struct, symprec=args.tol)
    data = sym.get_symmetry_dataset()

    print("Initial structure has {} atoms".format(struct.num_sites))
    print("\tSpace group number: {}".format(data['number']))
    print("\tInternational symbol: {}".format(data['international']))
    print("\tLattice type: {}".format(sym.get_lattice_type()))

    # seekpath conventional cell definition different from spglib
    std = spglib.refine_cell(sym._cell, symprec=args.tol)
    seek_data = seekpath.get_path(std)

    # now remake the structure
    lattice = seek_data['conv_lattice']
    scaled_positions = seek_data['conv_positions']
    numbers = seek_data['conv_types']
    species = [sym._unique_species[i - 1] for i in numbers]
    conv = Structure(lattice, species, scaled_positions)
    conv.get_sorted_structure().to(filename="{}_conv".format(args.file),
                                   fmt=args.output)

    print("Final structure has {} atoms".format(conv.num_sites))
Beispiel #20
0
    def refine(self, symprec=1e-5, angle_tolerance=-1.0, isPersist=False):
        """
        redefine structure which may change the cell's shape. 
        
        Arguments:
            symprec (default=1e-5, symmetry tolerance): distance tolerance in Cartesian coordinates to find crystal symmetry.
            angle_tolerance (default=-1.0): An experimental argument that controls angle tolerance between basis vectors.
                Normally it is not recommended to use this argument.
            isPersist (default=False): whether to save to the database.
        
        Returns:
            structureFactory's object.
            
        通过找对称性,重新定义晶胞。注意:可能会改变晶胞形状。
        
        参数:
            symprec (default=1e-5):找结构对称性时,采用的精度。
            angle_tolerance (default=-1.0):找结构对称性时,控制晶胞基矢之间的角度容差值。
            isPersist (default=False):是否持久化,即将结构保存到数据库中。
            
        返回:
            结构操作对象。
        """
        import spglib

        structure = self.structure
        cell = structure.formatting('cell')
        cell = (cell['lattice'], cell['positions'], cell['numbers'])
        cell_new = spglib.refine_cell(cell,
                                      symprec=symprec,
                                      angle_tolerance=angle_tolerance)
        if cell_new is None:
            raise StructureFactoryError('The search is filed')
        cell_new = {
            'lattice': cell_new[0],
            'positions': cell_new[1],
            'numbers': cell_new[2]
        }
        structure.update_by_cell(cell_new, isPersist=isPersist)
        self.structure = structure
        return self
Beispiel #21
0
 def refined_atoms(self):
     """Refine atoms based on spacegroup data."""
     phonopy_atoms = (
         self._atoms.lattice_mat,
         self._atoms.frac_coords,
         self._atoms.atomic_numbers,
     )
     lattice, scaled_positions, numbers = spglib.refine_cell(
         phonopy_atoms, self._symprec, self._angle_tolerance)
     elements = self._atoms.elements
     el_dict = {}
     for i in elements:
         el_dict.setdefault(Specie(i).Z, i)
     ref_elements = [el_dict[i] for i in numbers]
     ref_atoms = Atoms(
         lattice_mat=lattice,
         elements=ref_elements,
         coords=scaled_positions,
         cartesian=False,
     )
     return ref_atoms
Beispiel #22
0
    def __init__(self, structure, symprec=1e-3):
        self.structure = structure

        # use sym as a quick way to access the cell data
        sym = SpacegroupAnalyzer(structure, symprec=symprec)
        self._spg_data = sym.get_symmetry_dataset()

        # make primitive and conventional cell from seekpath output
        std = spglib.refine_cell(sym._cell, symprec=symprec)
        self._seek_data = seekpath.get_path(std)

        prim_lattice = self._seek_data["primitive_lattice"]
        prim_scaled_positions = self._seek_data["primitive_positions"]
        prim_numbers = self._seek_data["primitive_types"]
        prim_atoms = [sym._unique_species[i - 1] for i in prim_numbers]
        self.prim = Structure(prim_lattice, prim_atoms, prim_scaled_positions)

        conv_lattice = self._seek_data["conv_lattice"]
        conv_scaled_positions = self._seek_data["conv_positions"]
        conv_numbers = self._seek_data["conv_types"]
        conv_atoms = [sym._unique_species[i - 1] for i in conv_numbers]
        self.conv = Structure(conv_lattice, conv_atoms, conv_scaled_positions)
Beispiel #23
0
def refine_cell(structure, symprec=1e-3, verbosity=0):
    """
    Refines the input crystal structure to within a tolerance using `spglib`.

    Args:
        structure: :class:`simulation.Structure` object with a crystal structure.
        symprec: Float with the Cartesian distance tolerance.
        verbosity: Integer with the level of standard output verbosity.

    Returns: :class:`simulation.Structure` object with the refined 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.refine_cell(_structure_to_cell(structure), symprec=symprec)
    if not _check_spglib_success(cell, func='refine_cell',
                                 verbosity=verbosity):
        return structure
    _cell_to_structure(cell, structure, rev_lookup)
    return structure
Beispiel #24
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--file', default='POSCAR', type=str,
                        help='path to input file')
    parser.add_argument('-t', '--tol', default=1e-3, type=float,
                        help='symmetry tolerance (default 1e-3)')
    parser.add_argument('-o', '--output', default='poscar',
                        help='output file format')
    args = parser.parse_args()

    struct = Structure.from_file(args.file)
    sym = SpacegroupAnalyzer(struct, symprec=args.tol)
    data = sym.get_symmetry_dataset()

    print('Initial structure has {} atoms'.format(struct.num_sites))
    print('\tSpace group number: {}'.format(data['number']))
    print('\tInternational symbol: {}'.format(data['international']))
    print('\tLattice type: {}'.format(sym.get_lattice_type()))

    # first standardise the cell using the tolerance we want (seekpath has no
    # tolerance setting)
    std = spglib.refine_cell(sym._cell, symprec=args.tol)
    seek_data = seekpath.get_path(std)

    transform = seek_data['primitive_transformation_matrix']

    # now remake the structure
    lattice = seek_data['primitive_lattice']
    scaled_positions = seek_data['primitive_positions']
    numbers = seek_data['primitive_types']
    species = [sym._unique_species[i - 1] for i in numbers]
    prim = Structure(lattice, species, scaled_positions)
    prim.get_sorted_structure().to(filename='{}_prim'.format(args.file),
                                   fmt=args.output)

    print('Final structure has {} atoms'.format(prim.num_sites))
    print('Conv -> Prim transformation matrix:')
    print('\t' + str(transform).replace('\n', '\n\t'))
Beispiel #25
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 = refine_cell(self._spglib_cell(), symprec=symprec)
        if search is None:
            raise RuntimeError("Ideal cell could not be found.")

        lattice_vectors, scaled_positions, numbers = search

        # Preserve whatever subclass this object already is
        # This is important because some properties can be extracted from
        # source files (e.g. PWSCF output files)
        return type(self)(
            unitcell=(Atom(int(Z), coords=coords)
                      for Z, coords in zip(numbers, scaled_positions)),
            lattice_vectors=lattice_vectors,
            source=self.source,
        )
    def refine(self, symprec=1e-5, angle_tolerance=-1.0):
        """
        refine structure which can change the cell's shape
        
        Arguments:
            symprec (symmetry tolerance): distance tolerance in Cartesian coordinates to find crystal symmetry
            angle_tolerance: An experimental argument that controls angle tolerance between basis vectors.
                Normally it is not recommended to use this argument.
    
        """
        cell = self.structure.formatting('cell')
        cell = (cell['lattice'], cell['positions'], cell['numbers'])
        newcell = spglib.refine_cell(cell,
                                     symprec=symprec,
                                     angle_tolerance=angle_tolerance)

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

            self.structure.pop()  # delete old object
            self.structure = Structure().append(poscar)
            return self.structure
Beispiel #27
0
def get_standerdized_cell(atoms_orig):
    cell, scaled_positions, numbers = spglib.refine_cell(atoms_orig)
    return _make_new_atoms(cell, scaled_positions, numbers)
Beispiel #28
0
 def get_refined_cell(self, symprec=1e-5):
     spg_cell = (self.lattice, self.positions, self.atoms)
     lattice, positions, atoms = spglib.refine_cell(spg_cell, symprec)
     return self.__class__(lattice, positions, atoms)
Beispiel #29
0
print('')
print("[get_symmetry_dataset] ['rotations'], ['translations']")
print("  Symmetry operations of Rutile unitcell are:")
for i, (rot,trans) in enumerate(zip(dataset['rotations'],
                                    dataset['translations'])):
    print("  --------------- %4d ---------------" % (i + 1))
    print("  rotation:")
    for x in rot:
        print("     [%2d %2d %2d]" % (x[0], x[1], x[2]))
    print("  translation:")
    print("     (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2]))
print('')

print("[refine_cell]")
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,
Beispiel #30
0
 def get_standarized(self):
     refinedCell = (spglib.refine_cell(self.cellSymmetry, symprec=1e-1))
     return spglib.get_symmetry_dataset(self.standarize()),\
            spglib.get_symmetry_dataset(refinedCell)
Beispiel #31
0
    def spacegroup(self):
        '''international ID of determined spacegroup'''
        sg = spglib.get_symmetry_dataset(spglib.refine_cell(
            self.atoms))['international']

        return sg.replace('/', ':')
Beispiel #32
0
def launch_aiida():
    import spglib
    from phonopy.interface.vasp import (read_vasp_from_strings,
                                        get_vasp_structure_lines)
    from phonopy.structure.atoms import PhonopyAtoms
    from aiida.plugins import DataFactory, WorkflowFactory
    from aiida.engine import run, submit
    from aiida_phonopy.common.utils import phonopy_atoms_to_structure

    Dict = DataFactory('dict')
    unitcell_str = """ Na Cl
   1.00000000000000
     5.6903014761756712    0.0000000000000000    0.0000000000000000
     0.0000000000000000    5.6903014761756712    0.0000000000000000
     0.0000000000000000    0.0000000000000000    5.6903014761756712
   4   4
Direct
  0.0000000000000000  0.0000000000000000  0.0000000000000000
  0.0000000000000000  0.5000000000000000  0.5000000000000000
  0.5000000000000000  0.0000000000000000  0.5000000000000000
  0.5000000000000000  0.5000000000000000  0.0000000000000000
  0.5000000000000000  0.5000000000000000  0.5000000000000000
  0.5000000000000000  0.0000000000000000  0.0000000000000000
  0.0000000000000000  0.5000000000000000  0.0000000000000000
  0.0000000000000000  0.0000000000000000  0.5000000000000000"""

    lat, pos, num = spglib.refine_cell(
        read_vasp_from_strings(unitcell_str).to_tuple())
    cell = PhonopyAtoms(cell=lat, scaled_positions=pos, numbers=num)
    cell = read_vasp_from_strings(
        '\n'.join(get_vasp_structure_lines(cell)))
    structure = phonopy_atoms_to_structure(cell)

    base_incar_dict = {
        'PREC': 'Accurate',
        'IBRION': -1,
        'EDIFF': 1e-8,
        'NELMIN': 5,
        'NELM': 100,
        'ENCUT': 520,
        'IALGO': 38,
        'ISMEAR': 0,
        'SIGMA': 0.01,
        # 'GGA': 'PS',
        'LREAL': False,
        'lcharg': False,
        'lwave': False,
    }

    base_config = {'code_string': 'vasp544mpi@stern',
                   'kpoints_density': 0.5,  # k-point density,
                   'potential_family': 'PBE.54',
                   'potential_mapping': {'Na': 'Na_pv', 'Cl': 'Cl'},
                   'options': {'resources': {'parallel_env': 'mpi*',
                                             'tot_num_mpiprocs': 16},
                               'max_wallclock_seconds': 3600 * 10}}
    base_parser_settings = {'add_energies': True,
                            'add_forces': True,
                            'add_stress': True}
    forces_config = base_config.copy()
    forces_config.update({'parser_settings': base_parser_settings,
                          'parameters': base_incar_dict})
    nac_config = base_config.copy()
    nac_parser_settings = {'add_born_charges': True,
                           'add_dielectrics': True}
    nac_parser_settings.update(base_parser_settings)
    nac_incar_dict = {'lepsilon': True}
    nac_incar_dict.update(base_incar_dict)
    nac_config.update({'parser_settings': nac_parser_settings,
                       'parameters': nac_incar_dict})

    PhononPhonopy = WorkflowFactory('phonopy.phonopy')
    builder = PhononPhonopy.get_builder()
    builder.structure = structure
    builder.calculator_settings = Dict(dict={'forces': forces_config,
                                             'nac': nac_config})
    builder.run_phonopy = Bool(True)
    builder.remote_phonopy = Bool(True)
    builder.code_string = Str('phonopy@stern')
    builder.phonon_settings = Dict(
        dict={'mesh': 50.0,
              'supercell_matrix': [1, 1, 1],
              'distance': 0.01,
              'is_nac': True})
    builder.symmetry_tolerance = Float(1e-5)
    builder.options = Dict(dict=base_config['options'])
    builder.metadata.label = "NaCl 2x2x2 phonon test on stern"
    builder.metadata.description = "NaCl 2x2x2 phonon test on stern"

    # Chose how to run the calculation
    run_by_deamon = True
    if not run_by_deamon:
        result = run(builder)
        print(result)
    else:
        future = submit(builder)
        print(future)
        print('Running workchain with pk={}'.format(future.pk))
Beispiel #33
0
 def spacegroup(self):
     '''international number of determined spacegroup'''
     return spglib.get_symmetry_dataset(spglib.refine_cell(
         self.atoms))['international']
Beispiel #34
0
print('')
print("[get_symmetry_dataset] ['rotations'], ['translations']")
print("  Symmetry operations of Rutile unitcell are:")
for i, (rot,trans) in enumerate(zip(dataset['rotations'],
                                    dataset['translations'])):
    print("  --------------- %4d ---------------" % (i + 1))
    print("  rotation:")
    for x in rot:
        print("     [%2d %2d %2d]" % (x[0], x[1], x[2]))
    print("  translation:")
    print("     (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2]))
print('')

print("[refine_cell]")
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,
Beispiel #35
0
  print "single conv"
  print "\nvectors"
  for i in range(3):
    print "   {0:15.12f} {1:15.12f} {2:15.12f}".format(cell[i][0],cell[i][1],cell[i][2])
  print "\nfractional"
  list=[]
  for i in range(len(structure)):
    eatom= dataset['equivalent_atoms'][i]
    if eatom not in list:
      list.append(eatom)
    print "{0:>3}{1:<2}     {2:<10}  {3:<10} {4:<10}".format(structure.get_chemical_symbols()[i], eatom, structure.get_scaled_positions()[i][0], structure.get_scaled_positions()[i][1], structure.get_scaled_positions()[i][2])
  print "======================================================="

#Refine cell ========================================================================
if True:
  lattice, scaled_positions, numbers = spglib.refine_cell(structure, symprec= symprec)  
  print "\n#GDIS Input\n==============  Refined cell ======================"
  print "single conv"
  print "\nvectors"
  for i in range(3):
    print "   {0:15.12f} {1:15.12f} {2:15.12f}".format(lattice[i][0],lattice[i][1],lattice[i][2])
  print "\nfractional"
  for i in range(len(structure)):
    print "{0:>3}     {1:<10}  {2:<10} {3:<10}".format(chemical_symbols[numbers[i]], scaled_positions[i][0], scaled_positions[i][1], scaled_positions[i][2])
  print "======================================================="


# Primitive cell =====================================================================
if True:
  lattice, scaled_positions, numbers= spglib.find_primitive(structure, symprec= symprec)