예제 #1
0
파일: symmetry.py 프로젝트: tilde-lab/tilde
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))
예제 #2
0
    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
예제 #3
0
파일: symmetry.py 프로젝트: santiama/tilde
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))
예제 #4
0
    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
예제 #5
0
    def get_displacement(self, atoms: Atoms):
        if not all(atoms.get_pbc()):
            return space.free()

        return space.periodic_general(self.box, fractional_coordinates=False)