示例#1
0
 def setUpClass(cls):
     cls.al_fcc = ase_to_pyiron(bulk("Al", cubic=True))
     cls.fe_bcc = ase_to_pyiron(bulk("Fe", cubic=True))
     cls.ti_hcp = ase_to_pyiron(bulk("Ti", orthorhombic=True))
     cls.si_dia = ase_to_pyiron(bulk("Si", cubic=True))
     cls.al_fcc_4 = CrystalStructure(element="Al",
                                     bravais_basis="fcc",
                                     lattice_constants=4
                                     ).repeat(4)
 def test_check_diamond(self):
     al_fcc = ase_to_pyiron(bulk("Al", cubic=True))
     fe_bcc = ase_to_pyiron(bulk("Fe", cubic=True))
     ti_hcp = ase_to_pyiron(bulk("Ti", orthorhombic=True))
     si_dia = ase_to_pyiron(bulk("Si", cubic=True))
     self.assertFalse(check_diamond(structure=al_fcc))
     self.assertFalse(check_diamond(structure=fe_bcc))
     self.assertFalse(check_diamond(structure=ti_hcp))
     self.assertTrue(check_diamond(structure=si_dia))
示例#3
0
    def surface_hkl(lattice, hkl, layers, vacuum=1.0, center=False, pbc=True):
        """
        Use ase.build.surface to build a surface with surface normal (hkl).

        Args:
            lattice (pyiron_atomistics.atomistics.structure.atoms.Atoms/str): bulk Atoms
                instance or str, e.g. "Fe", from which to build the surface
            hkl (list): miller indices of surface to be created
            layers (int): # of atomic layers in the surface
            vacuum (float): vacuum spacing
            center (bool): shift all positions to center the surface
                in the cell

        Returns:
            pyiron_atomistics.atomistics.structure.atoms.Atoms instance: Required surface
        """
        # https://gitlab.com/ase/ase/blob/master/ase/lattice/surface.py
        state.publications.add(publication_ase())

        surface = ase_surf(lattice, hkl, layers)
        z_max = np.max(surface.positions[:, 2])
        surface.cell[2, 2] = z_max + vacuum
        if center:
            surface.positions += 0.5 * surface.cell[2] - [0, 0, z_max / 2]
        surface.pbc = pbc
        return ase_to_pyiron(surface)
示例#4
0
    def build(self):
        """
        Call Atomsk with the options accumulated so far.

        Returns:
            :class:`.Atoms`: new structure
        """
        self._options.append("- exyz")  # output to stdout as exyz format
        with tempfile.TemporaryDirectory() as temp_dir:
            if self._structure is not None:
                write(
                    os.path.join(temp_dir, "input.exyz"),
                    self._structure,
                    format="extxyz",
                )
            proc = subprocess.run(
                ["atomsk", *" ".join(self._options).split()],
                capture_output=True,
                cwd=temp_dir,
            )
            output = proc.stdout.decode("utf8")
            for l in output.split("\n"):
                if l.strip().startswith("X!X ERROR:"):
                    raise AtomskError(f"atomsk returned error: {output}")
            return ase_to_pyiron(read(io.StringIO(output), format="extxyz"))
示例#5
0
 def test_strain(self):
     bulk = StructureFactory().ase.bulk('Fe', cubic=True)
     a_0 = bulk.cell[0, 0]
     b = 0.5 * np.sqrt(3) * a_0
     structure = ase_to_pyiron(
         BodyCenteredCubic(symbol='Fe',
                           directions=[[-1, 0, 1], [1, -2, 1], [1, 1, 1]],
                           latticeconstant=a_0))
     L = 100
     structure = structure.repeat(
         (*np.rint(L / structure.cell.diagonal()[:2]).astype(int), 1))
     voro = Voronoi(structure.positions[:, :2])
     center = voro.vertices[np.linalg.norm(
         voro.vertices - structure.cell.diagonal()[:2] * 0.5,
         axis=-1).argmin()]
     structure.positions[:, 2] += b / (2 * np.pi) * np.arctan2(
         *(structure.positions[:, :2] - center).T[::-1])
     structure.center_coordinates_in_unit_cell()
     r_0 = 0.9 * L / 2
     r = np.linalg.norm(structure.positions[:, :2] - center, axis=-1)
     core_region = (r < r_0) * (r > 10)
     strain = structure.analyse.get_strain(bulk, num_neighbors=8)
     strain = strain[core_region]
     positions = structure.positions[core_region, :2]
     x = positions - center
     eps_yz = b / (4 * np.pi) * x[:, 0] / np.linalg.norm(x, axis=-1)**2
     eps_xz = -b / (4 * np.pi) * x[:, 1] / np.linalg.norm(x, axis=-1)**2
     self.assertLess(np.absolute(eps_yz - strain[:, 1, 2]).max(), 0.01)
     self.assertLess(np.absolute(eps_xz - strain[:, 0, 2]).max(), 0.01)
示例#6
0
    def high_index_surface(
        self,
        element,
        crystal_structure,
        lattice_constant,
        terrace_orientation=None,
        step_orientation=None,
        kink_orientation=None,
        step_down_vector=None,
        length_step=3,
        length_terrace=3,
        length_kink=1,
        layers=60,
        vacuum=10,
    ):
        """
        Gives a slab positioned at the bottom with the high index surface computed by high_index_surface_info().
        Args:
            element (str): The parent element eq. "N", "O", "Mg" etc.
            crystal_structure (str): The crystal structure of the lattice
            lattice_constant (float): The lattice constant
            terrace_orientation (list): The miller index of the terrace. default: [1,1,1]
            step_orientation (list): The miller index of the step. default: [1,1,0]
            kink_orientation (list): The miller index of the kink. default: [1,1,1]
            step_down_vector (list): The direction for stepping down from the step to next terrace. default: [1,1,0]
            length_terrace (int): The length of the terrace along the kink direction in atoms. default: 3
            length_step (int): The length of the step along the step direction in atoms. default: 3
            length_kink (int): The length of the kink along the kink direction in atoms. default: 1
            layers (int): Number of layers of the high_index_surface. default: 60
            vacuum (float): Thickness of vacuum on the top of the slab. default:10

        Returns:
            slab: pyiron_atomistics.atomistics.structure.atoms.Atoms instance Required surface
        """
        basis = self.crystal(
            element=element,
            bravais_basis=crystal_structure,
            lattice_constant=lattice_constant,
        )
        high_index_surface, _, _ = self.high_index_surface_info(
            element=element,
            crystal_structure=crystal_structure,
            lattice_constant=lattice_constant,
            terrace_orientation=terrace_orientation,
            step_orientation=step_orientation,
            kink_orientation=kink_orientation,
            step_down_vector=step_down_vector,
            length_step=length_step,
            length_terrace=length_terrace,
            length_kink=length_kink,
        )
        surf = ase_surf(basis, high_index_surface, layers, vacuum)
        sga = SpacegroupAnalyzer(pyiron_to_pymatgen(ase_to_pyiron(surf)))
        pmg_refined = sga.get_refined_structure()
        slab = pymatgen_to_pyiron(pmg_refined)
        slab.positions[:,
                       2] = slab.positions[:, 2] - np.min(slab.positions[:, 2])
        slab.set_pbc(True)
        return slab
示例#7
0
    def db_entry(self):
        """
        Generate the initial database entry

        Returns:
            (dict): db_dict
        """
        db_dict = super(InteractiveWrapper, self).db_entry()
        if self.structure:
            if isinstance(self.structure, PAtoms):
                parent_structure = self.structure.get_parent_basis()
            else:
                parent_structure = ase_to_pyiron(
                    self.structure).get_parent_basis()
            db_dict["ChemicalFormula"] = parent_structure.get_chemical_formula(
            )
        return db_dict
示例#8
0
 def from_ase(ase_atoms):
     return ase_to_pyiron(ase_atoms)
示例#9
0
    def surface(
            element,
            surface_type,
            size=(1, 1, 1),
            vacuum=1.0,
            center=False,
            pbc=True,
            **kwargs,
    ):
        """
        Generate a surface based on the ase.build.surface module.

        Args:
            element (str): Element name
            surface_type (str): The string specifying the surface type generators available through ase (fcc111,
            hcp0001 etc.)
            size (tuple): Size of the surface
            vacuum (float): Length of vacuum layer added to the surface along the z direction
            center (bool): Tells if the surface layers have to be at the center or at one end along the z-direction
            pbc (list/numpy.ndarray): List of booleans specifying the periodic boundary conditions along all three
                                      directions.
            **kwargs: Additional, arguments you would normally pass to the structure generator like 'a', 'b',
            'orthogonal' etc.

        Returns:
            pyiron_atomistics.atomistics.structure.atoms.Atoms instance: Required surface

        """
        # https://gitlab.com/ase/ase/blob/master/ase/lattice/surface.py
        if pbc is None:
            pbc = True
        state.publications.add(publication_ase())
        for surface_class in [
                add_adsorbate,
                add_vacuum,
                bcc100,
                bcc110,
                bcc111,
                diamond100,
                diamond111,
                fcc100,
                fcc110,
                fcc111,
                fcc211,
                hcp0001,
                hcp10m10,
                mx2,
                hcp0001_root,
                fcc111_root,
                bcc111_root,
                root_surface,
                root_surface_analysis,
                ase_surf,
        ]:
            if surface_type == surface_class.__name__:
                surface_type = surface_class
                break
        if isinstance(surface_type, types.FunctionType):
            if center:
                surface = surface_type(symbol=element,
                                       size=size,
                                       vacuum=vacuum,
                                       **kwargs)
            else:
                surface = surface_type(symbol=element, size=size, **kwargs)
                z_max = np.max(surface.positions[:, 2])
                surface.cell[2, 2] = z_max + vacuum
            surface.pbc = pbc
            return ase_to_pyiron(surface)
        else:
            raise ValueError(f"Surface type {surface_type} not recognized.")
示例#10
0
 def _final_struct_to_hdf(self):
     with self._hdf5.open("output") as hdf5:
         structure = self.get_structure(frame=-1)
         if not isinstance(structure, Atoms):
             structure = ase_to_pyiron(structure)
         structure.to_hdf(hdf5)
示例#11
0
 def read(self, *args, **kwargs):
     return ase_to_pyiron(ase_read(*args, **kwargs))
示例#12
0
 def crystal(self, *args, **kwargs):
     return ase_to_pyiron(ase_crystal(*args, **kwargs))
示例#13
0
 def bulk(self, *args, **kwargs):
     return ase_to_pyiron(ase_bulk(*args, **kwargs))
示例#14
0
def pymatgen_to_pyiron(structure):
    return ase_to_pyiron(AseAtomsAdaptor.get_atoms(structure))