def apply_defect(self, number: int, defect_type: str = 'vac', supercell: List[int] = [1, 1, 1], element: str = '') -> Structure: ''' Apply the defects, i.e. make changes to the structure including removing, substitution and etc. @in - defect_type, str: - vac: randomly remove some sites with given number of atoms - subs: randomly substitute some sites with given element a number of substitution operations is need. - inte: not implemented yet - vint: not implemented yet - supercell, [int, int, int] - element, str, must be a valid element symbol @out - Structure ''' assert number >= 0, f"Number of defects should be non-negative" assert len(supercell) == 3, f"Length of supercell list must be 3" sc = self.old_structure.copy() sc.make_supercell(supercell) indices = random.sample(range(len(sc)), number) # Select the apply site if 'vac' == defect_type: rest_id = [i for i in range(len(sc)) if i not in indices] new_structure = sc[rest_id].copy() self.operations.append({'vacancy': number}) return new_structure elif 'subs' == defect_type: assert is_valid_symbol( element), f'Invalid element input: "{element}"' ops = {i: element for i in indices} trans = ReplaceSiteSpeciesTransformation(ops) new_structure = trans.apply_transformation(sc) new_structure.sort() self.operations.append({'substitution': number}) return new_structure elif 'inte' == defect_type: raise Exception( f'This type of defect ({defect_type}) is still in developing') elif 'vint' == defect_type: raise Exception( f'This type of defect ({defect_type}) is still in developing') else: raise Exception(f'Invalid defect type input: "{defect_type}"')
def replace_atom_NEB(prev_NEB_dir, this_NEB_dir, atom_nums, new_atom): NEB = VaspNEBInput.from_directory(prev_NEB_dir, True) atom_mapping = {k-1:new_atom for k in atom_nums} transformation = ReplaceSiteSpeciesTransformation(atom_mapping) for i in range(len(NEB['POSCARs'])): sd = NEB['POSCARs'][i].selective_dynamics NEB['POSCARs'][i].structure = transformation.apply_transformation(NEB['POSCARs'][i].structure) NEB['POSCARs'][i].comment = ' '.join(NEB['POSCARs'][i].site_symbols) NEB['POSCARs'][i].selective_dynamics = sd NEB['POTCAR'] = Potcar(NEB['POSCARs'][i].site_symbols) update_incar(vasp['POSCAR'].structure, vasp['INCAR']) NEB.write_input(this_NEB_dir) return
def replace_atom(prev_dir, this_dir, atom_nums, new_atom, optional_files=None, spin=0): Poscar.get_string = get_string_more_sigfig vasp = VaspInput.from_directory(prev_dir, optional_files) atom_mapping = {k-1:new_atom for k in atom_nums} transformation = ReplaceSiteSpeciesTransformation(atom_mapping) # Modifying POSCAR sd = vasp['POSCAR'].selective_dynamics if 'MAGMOM' in vasp['INCAR']: mm = vasp["INCAR"]['MAGMOM'] else: mm = None vasp['POSCAR'].structure = transformation.apply_transformation(vasp['POSCAR'].structure) vasp['POSCAR'].comment = ' '.join(vasp['POSCAR'].site_symbols) if sd: vasp['POSCAR'].selective_dynamics = sd # Creating new POTCAR symbols = vasp['POSCAR'].site_symbols for i in range(len(symbols)): if symbols[i] in ['Fe', 'Ti', 'V', 'Cr', 'Mn', 'Co', 'Ni', 'Cu']: symbols[i] += '_pv' elif symbols[i] in ['Sc']: symbols[i] += '_sv' for atom in atom_nums: mm[atom-1] = spin vasp['POTCAR'] = Potcar(symbols) # Modifying INCAR update_incar(vasp['POSCAR'].structure, vasp['INCAR']) if 'MAGMOM' in vasp['INCAR']: vasp['INCAR']['MAGMOM'] = mm vasp.write_input(this_dir) return
def test_to_from_dict(self): d = ReplaceSiteSpeciesTransformation({0: "Na"}).as_dict() t = ReplaceSiteSpeciesTransformation.from_dict(d) s = t.apply_transformation(self.struct) self.assertEqual(s.formula, "Na1 Li3 O4")
def test_apply_transformation(self): t = ReplaceSiteSpeciesTransformation({0: "Na"}) s = t.apply_transformation(self.struct) self.assertEqual(s.formula, "Na1 Li3 O4") str(t)
def create_SNL(dirbase, molecules, atoms, spc_present, num_each_spc, struct, s): layers = len(molecules) with MPRester("sm5RbuEp83T9Wo7P") as m: first_mol = struct[0] mono_or_homo = 0 #if system is a monolayer or homogeneous use its proper .cif file, else use generic WTe2 for heterostructures if (layers == 1) or all(x == first_mol for x in struct): mono_or_homo = 1 if (first_mol == molec[0]): structure = m.get_structure_by_material_id("mp-2815") #MoS2 ref = m.get_materials_id_references("mp-2815") r1 = np.array([0, 2, 4]) elif (first_mol == molec[1]): structure = m.get_structure_by_material_id("mp-1634") #MoSe2 ref = m.get_materials_id_references("mp-1634") r1 = np.array([0, 2, 4]) elif (first_mol == molec[2]): structure = m.get_structure_by_material_id("mp-602") #MoTe2 ref = m.get_materials_id_references("mp-602") r1 = np.array([1, 2, 5]) elif (first_mol == molec[3]): structure = m.get_structure_by_material_id("mp-224") #WS2 ref = m.get_materials_id_references("mp-224") r1 = np.array([0, 3, 5]) elif (first_mol == molec[4]): structure = m.get_structure_by_material_id("mp-1821") #WSe2 ref = m.get_materials_id_references("mp-1821") r1 = np.array([0, 2, 4]) elif (first_mol == molec[5]): structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) else: structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) # initialize history history = [] #half the height of original unit cell...to be used for vacuum length calculation later halfz = (structure.lattice.c) / 2 #make supercell if necessary levels = layers if (levels % 2 == 1): levels = levels + 1 tsuper = SupercellTransformation([[1, 0, 0], [0, 1, 0], [0, 0, (levels) / 2]]) history.append(history_node(tsuper)) supercell = tsuper.apply_transformation(structure) #make species replacements for heterostructures with more than one layer levels = layers if (levels % 2 == 1): levels = levels + 1 #if heterostructure has more than one layer: if (mono_or_homo == 0): for i in range(0, len(molecules)): if (molecules[i] == 5): continue else: TMspc = elems[atoms[2 * i]] TMloc = (levels * 2) + (i % 2) * (levels / 2) + int( np.floor((i) / 2)) DCspc = elems[atoms[2 * i + 1]] DCloc1 = (levels - (levels / 2)) - i % 2 * (levels / 2) + int( np.floor((i) / 2)) DCloc2 = levels + i % 2 * (levels / 2) + int( np.floor((i) / 2)) t1 = ReplaceSiteSpeciesTransformation({TMloc: TMspc}) t2 = ReplaceSiteSpeciesTransformation({DCloc1: DCspc}) t3 = ReplaceSiteSpeciesTransformation({DCloc2: DCspc}) history.append(history_node(t1)) history.append(history_node(t2)) history.append(history_node(t3)) supercell = t1.apply_transformation(supercell) supercell = t2.apply_transformation(supercell) supercell = t3.apply_transformation(supercell) #remove top layer of atom if necessary mult_factor = (layers + 1) / 2 - 1 r = r1 + (r1 + 1) * mult_factor tremove = RemoveSitesTransformation(r) if (layers % 2 == 1): supercell = tremove.apply_transformation(supercell) history.append(history_node(tremove)) #sort structure supercell = supercell.get_sorted_structure() #extend z-axis cell vector to add vaccuum to supercell vacuum = 10.0 old_lattice = supercell.lattice if (layers % 2 == 1): new_c = old_lattice.c - halfz + vacuum else: new_c = old_lattice.c + vacuum new_lattice = Lattice.from_parameters(old_lattice.a, old_lattice.b, new_c, old_lattice.alpha, old_lattice.beta, old_lattice.gamma) final_structure = Structure( new_lattice, supercell.species, supercell.frac_coords * np.array([1., 1., (old_lattice.c / new_lattice.c)]), coords_are_cartesian=False) hnode = { 'name': 'add vaccuum', 'url': '', 'description': 'increase z-direction cell vector by 10 angstroms' } history.append(hnode) #creat final SNL authors = [{"name": "Lindsay Bassman", "email": "*****@*****.**"}] projects = ["TMDC-Heterostructures"] remarks = [ "MAGICS calculation of band structures of 2D TMDC stacked heterostructures" ] final_snl = StructureNL(final_structure, authors, projects=projects, remarks=remarks, references=ref, history=history) #optionally write POSCAR file poscar = Poscar(final_structure, s) poscar.write_file(dirbase + "POSCAR", direct=False)