Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Returns
-------
primitive : Crystal
Crystal with primitive cell. If primitive cell is the same size as
the source Crystal, a reference to the source 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 = find_primitive(self._spglib_cell(),
symprec = symprec)
if search is None:
raise RuntimeError('Primitive cell could not be found.')
lattice_vectors, scaled_positions, numbers = search
if numbers.size == len(self): # Then there's no point in creating a new crystal
return self
atoms = [Atom(int(Z), coords = coords) for Z, coords in zip(numbers, scaled_positions)]
return Crystal(unitcell = atoms,
lattice_vectors = lattice_vectors,
source = self.source)
Notes
-----
spglib used to return (None,None,None) if no primitive cell can be found,
i.e. the given input Structure cannot be reduced, which can occur if (a) a
given Structure is already a primitive cell or (b) any other reason like a
too small value of `symprec`. Now [py]spglib >= 1.8.x seems to always
return data instead. We use :func:`is_same_struct` to determine if the
struct is irreducible. In that case we return None in order to keep the API
unchanged.
Also note that a primitive cell (e.g. with 2 atoms) can have a number of
different realizations. Therefore, you may not always get the primitive
cell which you would expect or get from other tools like Wien2K's sgroup.
Only things like `natoms` and the spacegroup can be safely compared.
"""
candidate = spglib2struct(spglib.find_primitive(struct.get_spglib(),
**kwds))
if is_same_struct(candidate, struct):
return None
else:
return candidate
"""
Args:
symprec:
angle_tolerance:
Returns:
"""
el_dict = {}
for el in set(self.get_chemical_elements()):
el_dict[el.AtomicNumber] = el
lattice = np.array(self.get_cell().T, dtype='double', order='C')
positions = np.array(self.get_scaled_positions(), dtype='double', order='C')
numbers = np.array(self.get_atomic_numbers(), dtype='intc')
cell, coords, atomic_numbers = spglib.find_primitive(cell=(lattice, positions, numbers),
symprec=symprec,
angle_tolerance=angle_tolerance)
# print atomic_numbers, type(atomic_numbers)
el_lst = [el_dict[i_a] for i_a in atomic_numbers]
# convert lattice vectors to standard (experimental feature!) TODO:
red_structure = Atoms(elements=el_lst,
scaled_positions=coords,
cell=cell)
space_group = red_structure.get_spacegroup(symprec)["Number"]
# print "space group: ", space_group
if space_group == 225: # fcc
alat = np.max(cell[0])
amat_fcc = alat * np.array([[1, 0, 1], [1, 1, 0], [0, 1, 1]])
red_structure.cell = amat_fcc
def find_primitive(self):
"""
Find a primitive version of the unit cell.
Returns:
A primitive cell in the input cell is searched and returned
as an Structure object. If no primitive cell is found, None is
returned.
"""
lattice, scaled_positions, numbers = spglib.find_primitive(
self._cell, symprec=self._symprec)
species = [self._unique_species[i - 1] for i in numbers]
return Structure(lattice, species, scaled_positions,
to_unit_cell=True).get_reduced_structure()
def find_primitive(self, symprec=1e-5):
new_spglib_cell = spg.find_primitive(self.spglib_cell, symprec=symprec)
return self.get_new_structure(new_spglib_cell)
"""
Finds the primitive unit cell of the crystal structure.
Args:
structure: :class:`qmpy.Structure` object with a crystal structure.
symprec: Float with the Cartesian distance tolerance.
verbosity: Integer with the level of standard output verbosity.
Returns: :class:`qmpy.Structure` object with the primitive 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.find_primitive(
_structure_to_cell(structure),
symprec=symprec
)
if not _check_spglib_success(cell,
func='find_primitive',
verbosity=verbosity):
return structure
_cell_to_structure(cell, structure, rev_lookup)
return structure
"""
Args:
symprec:
angle_tolerance:
Returns:
"""
el_dict = {}
for el in set(self.get_chemical_elements()):
el_dict[el.AtomicNumber] = el
lattice = np.array(self.get_cell().T, dtype='double', order='C')
positions = np.array(self.get_scaled_positions(), dtype='double', order='C')
numbers = np.array(self.get_atomic_numbers(), dtype='intc')
cell, coords, atomic_numbers = spglib.find_primitive(cell=(lattice, positions, numbers),
symprec=symprec,
angle_tolerance=angle_tolerance)
# print atomic_numbers, type(atomic_numbers)
el_lst = [el_dict[i_a] for i_a in atomic_numbers]
# convert lattice vectors to standard (experimental feature!) TODO:
red_structure = Atoms(elements=el_lst,
scaled_positions=coords,
cell=cell)
space_group = red_structure.get_spacegroup(symprec)["Number"]
# print "space group: ", space_group
if space_group == 225: # fcc
alat = np.max(cell[0])
amat_fcc = alat * np.array([[1, 0, 1], [1, 1, 0], [0, 1, 1]])
red_structure.cell = amat_fcc
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,
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)")