Example #1
0
    def __getitem__(self, frames):
        """
        Gets a subset of the trajectory if a slice is given, if an int is given, return a structure

        Args:
            frames (int, slice): int or slice of trajectory to return

        Return:
            (Trajectory, Structure) Subset of trajectory
        """
        if isinstance(frames, int) and frames < self.frac_coords.shape[0]:
            lattice = self.lattice if self.constant_lattice else self.lattice[frames]
            site_properties = self.site_properties[frames] if self.site_properties else None
            return Structure(Lattice(lattice), self.species, self.frac_coords[frames], site_properties=site_properties,
                             to_unit_cell=True)

        if isinstance(frames, slice):
            frames = np.arange(frames.start, frames.stop, frames.step)
        elif not (isinstance(frames, list) or isinstance(frames, np.ndarray)):
            try:
                frames = np.asarray(frames)
            except:
                raise Exception('Given accessor is not of type int, slice, tuple, list, or array')

        if (isinstance(frames, list) or isinstance(frames, np.ndarray)) and \
                (np.asarray([frames]) < self.frac_coords.shape[0]).all():
            if self.constant_lattice:
                lattice = self.lattice
            else:
                lattice = self.lattice[frames, :]
            return Trajectory(lattice, self.species, self.frac_coords[frames, :], self.time_step,
                              self.site_properties)
        else:
            warnings.warn('Some or all selected frames exceed trajectory length')
        return
Example #2
0
    def delete_bt_layer(self, bt, tol=0.25, axis=2):
        """
        Delete bottom or top layer of the structure.
        Args:
            bt (str): Specify whether it's a top or bottom layer delete. "b"
                means bottom layer and "t" means top layer.
            tol (float), Angstrom: Tolerance factor to determine whether two
                atoms are at the same plane.
                Default to 0.25
            axis (int): The direction of top and bottom layers. 0: x, 1: y, 2: z

        """
        if bt == "t":
            l1, l2 = (-1, -2)
        else:
            l1, l2 = (0, 1)

        l = self.lattice.abc[axis]
        layers = self.sort_sites_in_layers(tol=tol, axis=axis)
        l_dist = abs(layers[l1][0].coords[axis] - layers[l2][0].coords[axis])
        l_vector = [1, 1]
        l_vector.insert(axis, (l - l_dist) / l)
        new_lat = Lattice(self.lattice.matrix * np.array(l_vector)[:, None])

        layers.pop(l1)
        sites = reduce(lambda x, y: np.concatenate((x, y), axis=0), layers)
        new_sites = []
        l_dist = 0 if bt == "t" else l_dist
        l_vector = [0, 0]
        l_vector.insert(axis, l_dist)
        for i in sites:
            new_sites.append(PeriodicSite(i.specie, i.coords - l_vector,
                                          new_lat, coords_are_cartesian=True))
        self._sites = new_sites
        self._lattice = new_lat
Example #3
0
    def build_supercell_full_disorder(pstructure, scaling_matrix):
        """
        get a supercell with all disordered sites inside, should be used to generate a certain config based on instruction

        :param pstructure:
        :param scaling_matrix:
        :return:
        """
        scale_matrix = np.array(scaling_matrix, np.int16)
        if scale_matrix.shape != (3, 3):
            scale_matrix = np.array(scale_matrix * np.eye(3), np.int16)
        new_lattice = Lattice(np.dot(scale_matrix, pstructure._lattice.matrix))
        f_lat = lattice_points_in_supercell(scale_matrix)
        c_lat = new_lattice.get_cartesian_coords(f_lat)
        new_sites = []
        for site in pstructure.sites:
            icell = 0
            for v in c_lat:
                site_properties = deepcopy(site.properties)
                site_properties['icell'] = icell
                s = PeriodicSite(site.species,
                                 site.coords + v,
                                 new_lattice,
                                 properties=site_properties,
                                 coords_are_cartesian=True,
                                 to_unit_cell=False)
                new_sites.append(s)
                icell += 1
        new_charge = pstructure._charge * np.linalg.det(
            scale_matrix) if pstructure._charge else None
        return Structure.from_sites(new_sites, charge=new_charge), len(c_lat)
Example #4
0
 def setUp(self):
     self.si = Element("Si")
     coords = list()
     coords.append([0, 0, 0])
     coords.append([0.75, 0.5, 0.75])
     self.lattice = Lattice([[3.8401979337, 0.00, 0.00],
                             [1.9200989668, 3.3257101909, 0.00],
                             [0.00, -2.2171384943, 3.1355090603]])
     self.struct = Structure(self.lattice, [self.si, self.si], coords)
Example #5
0
    def setUp(self):
        l = Lattice([[3.52,0.0,2.033], [1.174,3.32,2.033], \
                [0.0,0.0,4.066]])
        s_bulk = Structure(l, ['Ga', 'As'], \
                [[0.0000, 0.0000, 0.0000], \
                [0.2500, 0.2500, 0.2500]])
        defect_site = PeriodicSite('As', [0.25, 0.25, 0.25], l)
        defect = Vacancy(s_bulk, defect_site, charge=1.)
        defect_entry = DefectEntry(defect, 0.)

        entries = [defect_entry]
        vbm = 0.2
        band_gap = 1.
        dpd = DefectPhaseDiagram(entries, vbm, band_gap)
        self.dp = DefectPlotter(dpd)
Example #6
0
    def __getitem__(self, frames):
        """
        Gets a subset of the trajectory if a slice is given, if an int is given, return a structure
        Args:
            frames (int, slice): int or slice of trajectory to return
        Return:
            (Trajectory, Structure) Subset of trajectory
        """
        # If trajectory is in displacement mode, return the displacements at that frame
        if self.coords_are_displacement:
            if isinstance(frames, int):
                if frames >= np.shape(self.frac_coords)[0]:
                    raise ValueError(
                        "Selected frame exceeds trajectory length")
                # For integer input, return the displacements at that timestep
                return self.frac_coords[frames]
            if isinstance(frames, slice):
                # For slice input, return a list of the displacements
                start, stop, step = frames.indices(len(self))
                return [self.frac_coords[i] for i in range(start, stop, step)]
            if isinstance(frames, (list, np.ndarray)):
                # For list input, return a list of the displacements
                pruned_frames = [
                    i for i in frames if i < len(self)
                ]  # Get rid of frames that exceed trajectory length
                if len(pruned_frames) < len(frames):
                    warnings.warn(
                        "Some or all selected frames exceed trajectory length")
                return [self.frac_coords[i] for i in pruned_frames]
            raise Exception(
                "Given accessor is not of type int, slice, list, or array")

        # If trajectory is in positions mode, return a structure for the given frame or trajectory for the given frames
        if isinstance(frames, int):
            if frames >= np.shape(self.frac_coords)[0]:
                raise ValueError("Selected frame exceeds trajectory length")
            # For integer input, return the structure at that timestep
            lattice = self.lattice if self.constant_lattice else self.lattice[
                frames]
            site_properties = (self.site_properties[frames]
                               if self.site_properties else None)
            site_properties = (self.site_properties[frames]
                               if self.site_properties else None)
            return Structure(
                Lattice(lattice),
                self.species,
                self.frac_coords[frames],
                site_properties=site_properties,
                to_unit_cell=True,
            )
        if isinstance(frames, slice):
            # For slice input, return a trajectory of the sliced time
            start, stop, step = frames.indices(len(self))
            pruned_frames = range(start, stop, step)
            lattice = (self.lattice if self.constant_lattice else
                       [self.lattice[i] for i in pruned_frames])
            frac_coords = [self.frac_coords[i] for i in pruned_frames]
            if self.site_properties is not None:
                site_properties = [
                    self.site_properties[i] for i in pruned_frames
                ]
            else:
                site_properties = None
            if self.frame_properties is not None:
                frame_properties = {}
                for key, item in self.frame_properties.items():
                    frame_properties[key] = [item[i] for i in pruned_frames]
            else:
                frame_properties = None
            return Trajectory(
                lattice,
                self.species,
                frac_coords,
                time_step=self.time_step,
                site_properties=site_properties,
                frame_properties=frame_properties,
                constant_lattice=self.constant_lattice,
                coords_are_displacement=False,
                base_positions=self.base_positions,
            )
        if isinstance(frames, (list, np.ndarray)):
            # For list input, return a trajectory of the specified times
            pruned_frames = [
                i for i in frames if i < len(self)
            ]  # Get rid of frames that exceed trajectory length
            if len(pruned_frames) < len(frames):
                warnings.warn(
                    "Some or all selected frames exceed trajectory length")
            lattice = (self.lattice if self.constant_lattice else
                       [self.lattice[i] for i in pruned_frames])
            frac_coords = [self.frac_coords[i] for i in pruned_frames]
            if self.site_properties is not None:
                site_properties = [
                    self.site_properties[i] for i in pruned_frames
                ]
            else:
                site_properties = None
            if self.frame_properties is not None:
                frame_properties = {}
                for key, item in self.frame_properties.items():
                    frame_properties[key] = [item[i] for i in pruned_frames]
            else:
                frame_properties = None
            return Trajectory(
                lattice,
                self.species,
                frac_coords,
                time_step=self.time_step,
                site_properties=site_properties,
                frame_properties=frame_properties,
                constant_lattice=self.constant_lattice,
                coords_are_displacement=False,
                base_positions=self.base_positions,
            )
        raise Exception(
            "Given accessor is not of type int, slice, tuple, list, or array")
Example #7
0
    crystal = Structure.from_file(
        filename=each_original_vasp)  # vasp file read -> structure 정보 접근

    for i in range(
            num_noised_files):  # original vasp file로부터 noised vasp 파일을 횟수만큼 생성

        # -------------------------- lattice 구조에 noise 부여하기 -----------------------------------------
        lattice_shell = np.zeros(
            shape=crystal.lattice.matrix.shape)  # 새로운 lattice matrix shell 생성

        noised_lattice = gaussian_noise_level * np.random.normal(
            0, 1, 9).reshape((3, 3))  # 기존 lattice matrix에 넣을 noise 생성

        new_lattice_matrix = crystal.lattice.matrix + noised_lattice  # 기존 lattice matrix에 noise 추가

        noised_lattice = Lattice(new_lattice_matrix)  # noise 추가된 새로운 lattice
        noised_crystal = Structure(
            noised_lattice, crystal.species,
            crystal.frac_coords)  # unitcell에 noise 추가된 결정구조
        # -----------------------------------------------------------------------------------------------

        # --------------------------- 결정구조 안의 각 원자에 대해 좌표 noise 부여 -------------------------
        for j in range(
                len(noised_crystal)):  # For each atom in the crystal structure
            noised_coord = list(gaussian_noise_level * np.random.normal(
                0, 1, 3).reshape(-1))  # internal coordinate noise
            noised_crystal[j] = noised_crystal[j].specie.name, noised_crystal[
                j].frac_coords + noised_coord  # 각 원자 좌표에 noise 추가
        # -----------------------------------------------------------------------------------------------

        # vasp file saved