class SymmetryFinder: accuracy = 1e-04 # recommended accuracy value = 0.0001 def __init__(self, accuracy=None): self.error = None self.accuracy=accuracy if accuracy else SymmetryFinder.accuracy self.angle_tolerance=4 def get_spacegroup(self, tilde_obj): try: symmetry = spg.get_spacegroup(tilde_obj['structures'][-1], symprec=self.accuracy, angle_tolerance=self.angle_tolerance) except Exception as ex: self.error = 'Symmetry finder error: %s' % ex else: symmetry = symmetry.split() self.i = symmetry[0] try: self.n = int( symmetry[1].replace("(", "").replace(")", "") ) except (ValueError, IndexError): self.n = 0 if self.n == 0: self.error = 'Symmetry finder error (probably, coinciding atoms)' 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))
def crystalAtoms(self, start_layer=0, end_layer=1, coordinates='orth_surface', sub_layers=False, minimal=True, ): atoms = self.crystal().atoms() if sub_layers: in_equal_layers = self.inequivalentLayers() repeats = int(np.ceil(end_layer/float(in_equal_layers))) atoms = atoms.repeat((1, 1, repeats + 1)) atoms.positions -= self.crystal().unitCell()*(repeats) start_layer += in_equal_layers -1 end_layer += in_equal_layers -1 atoms = orderAtoms(atoms, (2, 1, 0)) sl = slice(start_layer, end_layer) groups = groupAtoms(atoms)[::-1][sl] if len(groups) == 0: atoms = Atoms([], cell=atoms.get_cell(), pbc=atoms.get_pbc()) else: atoms, indices = groups[0] for group, indices in groups[1:]: atoms += group else: cell = atoms.unitCell() atoms = atoms.repeat((1, 1, end_layer-start_layer)) atoms.positions += cell*start_layer return atoms
class SymmetryFinder: accuracy = 1e-04 # recommended accuracy value = 0.0001 def __init__(self, accuracy=None): self.error = None self.accuracy = accuracy if accuracy else SymmetryFinder.accuracy self.angle_tolerance = 4 def get_spacegroup(self, tilde_obj): try: symmetry = spg.get_spacegroup(tilde_obj['structures'][-1], symprec=self.accuracy, angle_tolerance=self.angle_tolerance) except Exception as ex: self.error = 'Symmetry finder error: %s' % ex else: symmetry = symmetry.split() self.i = symmetry[0] try: self.n = int(symmetry[1].replace("(", "").replace(")", "")) except (ValueError, IndexError): self.n = 0 if self.n == 0: self.error = 'Symmetry finder error (probably, coinciding atoms)' 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))
def __init__(self, geometry=None, **kwargs) -> None: if geometry == None: atoms = Atoms(**kwargs) elif type(geometry) == ase.atoms.Atoms: atoms = geometry.copy() elif Path(geometry).is_file(): if str(Path(geometry).parts[-1]) == "geometry.in.next_step": atoms = ase.io.read(geometry, format="aims") else: try: atoms = ase.io.read(geometry) except Exception as excpt: logger.error(str(excpt)) raise Exception( "ASE was not able to recognize the file format, e.g., a non-standard cif-format." ) elif Path(geometry).is_dir(): raise Exception( "You specified a directory as input. The geometry must be a file." ) else: atoms = None assert type(atoms) == ase.atoms.Atoms, "Atoms not read correctly." # Get data from another Atoms object: numbers = atoms.get_atomic_numbers() positions = atoms.get_positions() cell = atoms.get_cell() celldisp = atoms.get_celldisp() pbc = atoms.get_pbc() constraint = [c.copy() for c in atoms.constraints] masses = atoms.get_masses() magmoms = None charges = None momenta = None if atoms.has("initial_magmoms"): magmoms = atoms.get_initial_magnetic_moments() if atoms.has("initial_charges"): charges = atoms.get_initial_charges() if atoms.has("momenta"): momenta = atoms.get_momenta() self.arrays = {} super().__init__( numbers=numbers, positions=positions, cell=cell, celldisp=celldisp, pbc=pbc, constraint=constraint, masses=masses, magmoms=magmoms, charges=charges, momenta=momenta, ) self._is_1d = None self._is_2d = None self._is_3d = None self._periodic_axes = None self._check_lattice_vectors() try: self.sg = ase.spacegroup.get_spacegroup(self, symprec=1e-2) except: self.sg = ase.spacegroup.Spacegroup(1) self.lattice = self.cell.get_bravais_lattice().crystal_family
def get_displacement(self, atoms: Atoms): if not all(atoms.get_pbc()): return space.free() return space.periodic_general(self.box, fractional_coordinates=False)