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
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
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)
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)
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)
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")
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