def strain_operation(): structs, fnames = read_structures() multi_structs(structs, fnames) for struct in structs: if isinstance(struct, Molecule): print( "cleave operation is only supported for periodic structure, skip !!" ) label.input print('input the strain component like :') print("0.01") print("it means aplly a strain of 1% along all directions") print("or") print("0.01 0.0 0.0") print("it means apply a strain of 1% along the x direction") print("or") print("0.01:0.03:5 0.0 0.0") print("it means to devide strain range into 5 parts") wait_sep() strain_str = wait() if strain_str == "0": return None tmp_list = strain_str.split(" ") if len(tmp_list) == 1: strain = [[float(tmp_list[0]), float(tmp_list[0]), float(tmp_list[0])]] elif len(tmp_list) == 3 and not ":" in strain_str: strain = [[float(x) for x in tmp_list]] elif len(tmp_list) == 3 and strain_str.count(":") % 2 == 0: tmp1 = [float(x) for x in tmp_list[0].split(":")] tmp2 = [float(x) for x in tmp_list[1].split(":")] tmp3 = [float(x) for x in tmp_list[2].split(":")] strain = [] if len(tmp1) == 3: x_range = np.linspace(tmp1[0], tmp1[1], int(tmp1[2])) else: x_range = tmp1 if len(tmp2) == 3: y_range = np.linspace(tmp2[0], tmp2[1], int(tmp2[2])) else: y_range = tmp2 if len(tmp3) == 3: z_range = np.linspace(tmp3[0], tmp3[1], int(tmp3[2])) else: z_range = tmp3 for ix in x_range: for iy in y_range: for iz in z_range: strain.append([ix, iy, iz]) else: print("Unknow format!!!") goto.input generate_strain_structure(structs, fnames, strain) return True
def get_conventional_cell(): structs, fnames = read_structures() multi_structs(structs, fnames) for struct, fname in zip(structs, fnames): sepline(ch='conventional cell', sp='-') ast = SpacegroupAnalyzer(struct) conv_st = ast.get_conventional_standard_structure() print(conv_st) sepline() print('save to ' + NAME + '_convention_' + fname + '.vasp') conv_st.to(filename=NAME + '_conventional_' + fname + '.vasp', fmt='poscar') sepline() return True
def get_primitive_cell(): structs, fnames = read_structures() multi_structs(structs, fnames) for struct, fname in zip(structs, fnames): sepline(ch='Primitive Cell', sp='-') ast = SpacegroupAnalyzer(struct) prim_st = ast.find_primitive() print(prim_st) sepline() print('save to ' + NAME + '_primitive_' + fname + '.vasp') prim_st.to(filename=NAME + '_primitive_' + fname + '.vasp', fmt='poscar') sepline() return True
def structure_symmetry(): structs, fnames = read_structures() multi_structs(structs, fnames) for struct, fname in zip(structs, fnames): if isinstance(struct, Structure): sa = SpacegroupAnalyzer(struct) print("file name: {}".format(fname)) print("{} : {}".format('Structure Type', 'periodicity')) print("{} : {}".format('Lattice Type', sa.get_lattice_type())) print("{} : {}".format('Space Group ID', sa.get_space_group_number())) print("{} : {}".format('International Symbol', sa.get_space_group_symbol())) print("{} : {}".format('Hall Symbol', sa.get_hall())) sepline() if isinstance(struct, Molecule): print("file name: {}".format(fname)) sa = PointGroupAnalyzer(struct) print("{} : {}".format('Structure Type', 'non-periodicity')) print("{} : {}".format('International Symbol', ast.get_pointgroup())) return True
def covert_operation(): structs, fnames = read_structures() if structs is None: return None multi_structs(structs, fnames) print('input the target file format') print("supported format: vasp lammps xsf cif nc json yaml xyz ...") print("for more information see ASE and Pymatgen manual.") wait_sep() fmt = wait() flag = True if fmt.lower() == 'vasp': fmt = 'poscar' for struct, fname in zip(structs, fnames): filename = NAME + '_' + fname.lower() + '.' + fmt if "POSCAR" in fname and flag: # it is a bug in pymatgen print("The string POSCAR in filename will be replaced by poscar") flag = False if fmt == 'lammps': system = structure2system(struct) system.to_lammps_lmp(filename) continue try: print("Write {0:20s} {1:s}".format(fname, 'Pymatgen:Struture')) struct.to(fmt, filename) except: print("Write {0:20s} {1:s} ".format(fname, 'Atoms:Atoms')) atoms = pmg2ase(struct) write(filename) return True
def cleave_operation(choice): # cleava surface structs,fnames=read_structures() multi_structs(structs,fnames) for struct in structs: if isinstance(struct,Molecule): print("cleave operation is only supported for periodic structure, skip !!") if choice=="1": print("Input the miller index, minimum size in angstroms of layers containing atomssupercell") print("and Minimize size in angstroms of layers containing vacuum like this:") print('1 0 0 | 5 | 5') print('it means miller index is [1,0,0]') print("min_slab_size is 5 Ang ") print("min_vacum_size is 5 Ang ") print("or like this : ") print('2 | 5 | 5') print('it will generate all slab with miller index less than 2') wait_sep() in_str=wait() len_para=len(in_str.split('|')[0].split()) if len_para==3: tmp_list=in_str.split('|') miller_index=[int(x) for x in tmp_list[0].strip().split() ] min_slab_size=float(tmp_list[1]) min_vac_size=float(tmp_list[2]) generate_selected_slab(structs,fnames,miller_index,min_slab_size,min_vac_size) return True elif len_para==1: tmp_list=in_str.split('|') max_index=int(tmp_list[0]) min_slab_size=float(tmp_list[1]) min_vac_size=float(tmp_list[2]) generate_all_slab(structs,fnames,max_index,min_slab_size,min_vac_size) return True else: print("unknow format") return None #cleave sphere elif choice=="2": print("Input the center atom index, sphere radius and vacuum layer thickness") print('1 3.5 15') print('it means the sphere will be selected according to the 1st atom') print("with the radius equals 5Ang, and vacuum layer thickness is 15 Ang") wait_sep() in_str=wait() para=in_str.split() center_atom=int(para[0])-1 radius=float(para[1]) vacuum=float(para[2]) generate_shell(structs,fnames,center_atom,radius,shell=None,vacuum=vacuum) return True #cleave shell elif choice=="3": print("Input the center atom index, start radius, shell thickness and") print("vacuum layer thickness") print('1 5 10 15') print('it means the ball shell will be selected according to the 1st atom') print("with the 5< r <15Ang, and vacuum layer thickness is 15 Ang") wait_sep() in_str="" while in_str=="": in_str=input().strip() para=in_str.split() center_atom=int(para[0])-1 radius=float(para[1]) shell=float(para[2]) vacuum=float(para[3]) generate_shell(structs,fnames,center_atom,radius,shell=shell,vacuum=vacuum) return True else: print("unkown choice") return None
def build_operation(choice): assert choice in ["1", "2", "3"] if choice == "1": structs, fnames = read_structures() multi_structs(structs, fnames) wait_sep() tip = """ Several options are available: a. A full 3x3 scaling matrix defining the linear combination the old lattice vectors. E.g., 2 1 0 0 1 0 0 0 3 generates a new structure with lattice vectors a' = 2a + b, b' = 3b, c' = c where a, b, and c are the lattice vectors of the original structure. b. An sequence of three scaling factors. E.g., 2 1 1 specifies that the supercell should have dimensions 2a x b x c. c. A number, which simply scales all lattice vectors by the same factor. """ print(tip) wait_sep() in_str = wait() scaling_list = [int(x) for x in in_str.split()] print("scaling list:") print(scaling_list) for struct, fname in zip(structs, fnames): if len(scaling_list) == 1: scales = scaling_list[0] sufix = [scales] elif len(scaling_list) == 3: scales = scaling_list elif len(scaling_list) == 9: scales = [ scaling_list[0:3], scaling_list[3:6], scaling_list[6:9] ] struct_cp = struct.copy() struct_cp.make_supercell(scales) fname = 'maptool_SC_' + fname + '.vasp' struct_cp.to(filename=fname, fmt='poscar') return True elif choice == "2": print('Only support for CNT now !') print('Input the n and m for tube') print('Paramter format, i.e. :') print('3 3') wait_sep() in_str = wait() m, n = [int(i) for i in in_str.split()] atoms = nanotube(m, n, vacuum=15) struct = ase2pmg(atoms) struct.to('POSCAR', 'CNT_' + str(m) + '-' + str(n) + '.vasp') return True else: data = { 'max_index': 2, 'min_vacum': 20, 'min_slab': 8, 'repeat': [3, 3, 1] } def read_adsorb_config(filename): with open(filename, 'r') as f: datas = f.readlines() list_data = [] for i in range(len(datas)): list_data.append( datas[i][0:datas[i].find('#')].strip().split('=')) defined_keys = [ 'method', 'crystal', 'molecule', 'max_index', 'min_vacum', 'min_slab', 'repeat' ] data_dict = {} for key in defined_keys: for li in list_data: if key in li[0]: data_dict[key] = li[1] data_dict['method'] = int(data_dict.get('method').strip()) data_dict['crystal'] = data_dict.get('crystal').strip() data_dict['molecule'] = data_dict.get('molecule').strip() data_dict['max_index'] = int( data_dict.get('max_index', '1').strip()) data_dict['min_vacum'] = int( data_dict.get('min_vacum', '15').strip()) data_dict['min_slab'] = int(data_dict.get('min_slab', '5').strip()) data_dict['repeat'] = [ int(x) for x in data_dict.get('repeat', '1 1 1').strip().split() ] return data_dict def proc_adsorb(cryst, mol, data): if data['method'] == 1: asf_slab = AdsorbateSiteFinder(cryst) ads_sites = asf_slab.find_adsorption_sites() ads_structs = asf_slab.generate_adsorption_structures( mol, repeat=data['repeat']) for i in range(len(ads_structs)): ads_struct = ads_structs[i] try: miller_str = [str(j) for j in cryst.miller_index] except: miller_str = ['adsorb'] filename = '_'.join(miller_str) + '-' + str(i) + '.vasp' ads_struct.to(filename=filename, fmt='POSCAR') else: slabs = generate_all_slabs(cryst, max_index=data['max_index'], min_slab_size=data['min_slab'], min_vacuum_size=data['min_vacum'], lll_reduce=True) for slab in slabs: asf_slab = AdsorbateSiteFinder(slab) ads_sites = asf_slab.find_adsorption_sites() ads_structs = asf_slab.generate_adsorption_structures( mol, repeat=data['repeat']) for i in range(len(ads_structs)): ads_struct = ads_structs[i] miller_str = [str(j) for j in slab.miller_index] filename = 'adsorb' + '_'.join(miller_str) + '-' + str( i) + '.vasp' ads_struct.to(filename=filename, fmt='POSCAR') filename = 'adsorb.cfg' if os.path.exists(filename): data = read_adsorb_config(filename) assert data['method'] in [1, 2] cryst = read_structures_from_file(data['crystal']) mol = read_structures_from_file(data['molecule']) proc_adsorb(cryst, mol, data) else: print('your choice ?') print('{} >>> {}'.format('1', 'read slab from file')) print('{} >>> {}'.format('2', 'build slab by bulk')) wait_sep() in_str = wait() choice = int(in_str) assert choice in [1, 2] data['method'] = choice tips = """\ Input the structure filename of molecule and substrate The first file should be molecule and 2nd for crystal supported structure format: xsf .vasp POSCAR .nc .json .xyz ... paramter format, i.e. : mol.xyz POSCAR""" structs, fnames = read_structures(tips) mol = structs[0] mlog.info("read mol from %s" % (fnames[0])) mlog.info(mol) assert isinstance(mol, Molecule), "the first file should be molecule" cryst = structs[1] mlog.info("read crystal from %s" % (fnames[1])) mlog.info(cryst) assert isinstance(cryst, Structure), "the second file should be crystal" proc_adsorb(cryst, mol, data) return True
def twod_operation(choice): assert choice in ["1", "2", "3", "4", "5", "6", "7"] if choice == "1": structs, fnames = read_structures() multi_structs(structs, fnames) print("input the supercell supercell factor") print('for x direction can be: 10 1 1') print('for y direction can be: 1 10 1') wait_sep() scale_str = wait() supercell = [int(x) for x in scale_str.split()] if (len(supercell) != 3): print('Unknown format') os._exit(0) if supercell[0] >= supercell[1]: direction = 0 # for x direction else: direction = 1 # for y direction print("input the strain range") print("example: 0.02:0.1:10 ") wait_sep() strain_str = wait() tmp = [float(x) for x in strain_str.split(":")] strain = [] if len(tmp) == 3: strain_range = np.linspace(tmp[0], tmp[1], int(tmp[2])) else: print("Unknown format") os._exit(0) print("input the index of atom need to be fixed") print("example: 1 10 11 20 ") print("0 means fix the atom automatically") wait_sep() atom_index_str = wait() if len(atom_index_str.split()) > 1: atom_index = [int(x) for x in atom_index_str.split("")] auto_fix = False else: atom_index = [int(atom_index_str)] auto_fix = True ripple(structs, fnames, supercell, direction, strain_range, atom_index, auto_fix) return True elif choice == "2": structs, fnames = read_structures() multi_structs(structs, fnames) print("Input the number of layers") wait_sep() in_str = wait() layer_number = int(in_str) print("Input the layer distance") wait_sep() in_str = wait() layer_distance = float(in_str) multi_layers(structs, fnames, layer_number, layer_distance) return True elif choice == "3": """ splitting sep .... . . . . . """ structs, fnames = read_structures() if len(structs) > 1: print("Splitting dont support multi-structures!!!") os._exit(0) atom_index, in_str = atom_selection(structs[0]) print("Input the splitting distance, 10 Ang is enough!") wait_sep() in_str = wait() SplitDistance = float(in_str) print("Numbers of splitting site, 50 sites are enough!") wait_sep() in_str = wait() NumberSplitSite = int(in_str) split(structs, fnames, atom_index, in_str, SplitDistance, NumberSplitSite, ProperDist=3.5, DenseFrac=0.75) return True elif choice == "4": structs, fnames = read_structures() multi_structs(structs, fnames) print("Input the new value of vacuum layer thickness") wait_sep() in_str = wait() wait_sep() nvac_layer_thickness = float(in_str) resize_vacuum(structs, fnames, nvac_layer_thickness) return True elif choice == "5": structs, fnames = read_structures() multi_structs(structs, fnames) for struct, fname in zip(structs, fnames): new_struct = move_to_zcenter(struct) new_struct.to(filename='z-center_' + fname + '.vasp', fmt='poscar') return True elif choice == 6: structs, fnames = read_structures() multi_structs(structs, fnames) try: import sympy except ImportError: print("You have to install sympy module") os._exit(0) print("Input the elastic of material by order : C11 C12 C22 C66") wait_sep() in_str = "" while in_str == "": in_str = input().strip().split() elastic_constant = [float(x) for x in in_str] if len(elastic_constant) != 4: print("You have to input C11 C12 C22 C66") return None C11 = elastic_constant[0] C12 = elastic_constant[1] C22 = elastic_constant[2] C66 = elastic_constant[3] print("Input applied force: e.x. 1.0 GPa nm") wait_sep() in_str = wait() sigma = float(in_str) circle_strain(structs, fnames, C11, C12, C22, C66, sigma) return True elif choice == "7": structs, fnames = read_structures() if len(structs) > 1: print("Constrain doesnot support multi-structures!!!") os._exit(0) atom_index, in_str = atom_selection(structs[0]) mlog.debug("constrained atom index") mlog.debug(' '.join(map(str, atom_index))) constrain(structs, fnames, atom_index, in_str) return True elif choice == "8": print('your choice ?') print('{} >>> {}'.format('1', 'input 2D structure from local disk')) print('{} >>> {}'.format('2', 'get 2D structure online')) wait_sep() in_str = wait() _choice = int(in_str) if _choice == "1": mpid = None structs, fnames = read_structures() if len(structs) > 1: print("Matching dont support multi-structures!!!") os._exit(0) else: print("Input the mp-id for your structure") wait_sep() in_str = wait() mpid = in_str struct = None film, substrates = get_mp_film_substrate(mpid=mpid, struct=struct) df = match_substrate(film, substrates) dumpfn(df.to_dict(), 'substrate_' + fnames[0] + '.json', indent=4) #df.to_csv('substrate.csv', sep=',', header=True, index=True) return True else: print("Unkonw choice") return None
def select_function(choice): r""" submenu for selecting function """ # structure operation if choice == "a1": print('{} >>> {}'.format('1', 'random structure generating')) print('{} >>> {}'.format('2', 'random perturbation for atom index')) print('{} >>> {}'.format('3', 'random disturbing for lattice matrix')) print('{} >>> {}'.format('4', 'random disturbing for atom position')) your_choice() in_str = wait() if in_str == "0": return None return random_operation(in_str) elif choice == "a2": return covert_operation() elif choice == "a3": print('{} >>> {}'.format('1', 'build supercell')) print('{} >>> {}'.format('2', 'build nanotube')) print('{} >>> {}'.format('3', 'build absorption configuration')) your_choice() in_str = wait() if in_str == "0": return None return build_operation(in_str) elif choice == "a4": print('{} >>> {}'.format('1', 'cleave surface')) print('{} >>> {}'.format('2', 'cleave sphere cluster')) print('{} >>> {}'.format('3', 'cleave shell structure')) your_choice() in_str = wait() if in_str == "0": return None return cleave_operation(in_str) elif choice == "a5": return strain_operation() elif choice == 'a6': print('{} >>> {}'.format('1', 'build rippled structure')) print('{} >>> {}'.format('2', 'build multi-layered structure')) print('{} >>> {}'.format('3', 'split multi-layered structure')) print('{} >>> {}'.format('4', 'resize vacuum layer')) print('{} >>> {}'.format('5', 'center atomic-layer along z direction')) print('{} >>> {}'.format('6', 'apply strain along different direction')) print('{} >>> {}'.format('7', 'constrain atom in specific range')) print('{} >>> {}'.format( '8', 'get a substrate for 2D material (online!!!)')) your_choice() in_str = wait() if in_str == "0": return None return twod_operation(in_str) # structure analysis elif choice == "b1": return structure_symmetry() elif choice == "b2": return structure_finger_print() elif choice == "b3": return structures_difference() elif choice == "b4": return get_primitive_cell() elif choice == "b5": return get_conventional_cell() elif choice == "b6": return get_xrd() # vasp in/out tools elif choice == "c1": structs, fnames = read_structures() if structs is None: return None multi_structs(structs, fnames) sepline(ch=' prepare intput files ', sp='-') your_choice() print('{} >>> {}'.format('1', 'prepare all files automatically')) print('{} >>> {}'.format('2', 'prepare INCAR file')) print('{} >>> {}'.format('3', 'prepare KPOINTS file')) print('{} >>> {}'.format('4', 'prepare POTCAR file')) label.input1 wait_sep() choice = wait() if choice == "0": return None elif choice == "1": return generate_all_input(structs, fnames) elif choice == "2": return generate_incar(structs, fnames) elif choice == "3": return generate_kpoint(structs, fnames) elif choice == "4": return generate_potcar(structs, fnames) else: print("unknown choice, check the input") goto.input1 elif choice == "cxx": sepline(ch=' summary output files ', sp='=') print('{} >>> {}'.format('1', 'describe OUCAR file')) print('{} >>> {}'.format('2', 'describe OSICAR file')) print('{} >>> {}'.format('3', 'describe vasprun.xml file')) label.input2 wait_sep() choice = wait() if choice == "0": return None if choice == "1": return describe_OUTCAR() elif choice == "2": return describe_OSICAR() elif choice == "3": return describe_vasprun() else: print("unknown choice, check the input") goto.input2 elif choice == "c2": sepline(ch=' vasp output analysis ', sp='-') print('{} >>> {}'.format('1 ', 'total density of states')) print('{} >>> {}'.format('2 ', 'projected density of states')) print('{} >>> {}'.format('3 ', 'band structure')) print('{} >>> {}'.format('4 ', 'projected band structure')) print('{} >>> {}'.format('5 ', 'select one band structure')) print('{} >>> {}'.format('6 ', 'charge density')) print('{} >>> {}'.format('7 ', 'spin density')) print('{} >>> {}'.format('8 ', 'charge density difference')) print('{} >>> {}'.format('9 ', 'spin density component: up/down')) print('{} >>> {}'.format('10', 'average charge density/potential')) print('{} >>> {}'.format('11', 'optics analysis')) print('{} >>> {}'.format('12', 'mechanical analysis')) print('{} >>> {}'.format('13', 'ab initio molecular dynamics analysis')) label.input3 wait_sep() choice = wait() if choice == "0": return None if choice == "1": return total_dos() elif choice == "2": return projected_dos() elif choice == "3": return band_structure() elif choice == "4": return projected_band_structure() elif choice == "5": return select_one_band_structure() elif choice == "6": return charge_density() elif choice == "7": return spin_density() elif choice == "8": return charge_density_diff() elif choice == "9": return spin_density_component() elif choice == "10": return chg_locp_average() elif choice == "11": return optics_analysis() elif choice == "12": return elastic_analysis() elif choice == "13": return aimd_analysis() else: print("unknown choice, check the input") goto.input3 # online exctraction elif choice == "e1": return get_mp_banddos() elif choice == "e2": return get_mp_structure() elif choice == "e3": return get_mp_properties() elif choice == "e4": return get_mp_phase_graph() elif choice == "e5": return get_oqmd_structure() elif choice == "88": os._exit(0) else: print("unknown choice, return now") return None