def prepareFiles(sp, images): default_texas = { 'IOPT': '1', 'IBRION': '3', 'POTIM': '0', 'MAXMOVE': '0.2', 'ILBFGSMEM': '20', 'LGLOBAL': '.TRUE.', 'LAUTOSCALE': '.TRUE.', 'INVCURV': '0.01', 'LLINEOPT': '.FALSE.', 'FDSTEP': '5E-3', 'LCLIMB': '.FALSE.', 'SPRING': '-5.0', 'NSIM': '4', 'NPAR': '4', 'LPLANE': '.TRUE.', 'LWAVE': '.FALSE.', 'LCHARG': '.FALSE.', 'ICHARG': '2', 'LREAL': '.FALSE.', 'ENCUT': '500', 'ISIF': 2, 'EDIFF': 1e-5, 'LDAU': '.FALSE.', 'NSW': 200, 'IMAGES': images, 'EDIFFG': -0.05 } vasp_set = MITRelaxSet(sp, user_incar_settings=default_texas) vasp_set.write_input("./neb/")
def setup_vasp(pmg_s, n_e): """ :param pmg_s: Pymatgen Structure object :param n_e: Number of electrons to add :return: A VaspSet """ nelect = MITRelaxSet(pmg_s).nelect if n_e > 0: print("###################################") print("# BE CAREFUL, YOU ADDED ELECTRONS #") print("###################################") nelect += n_e uis = {'NELECT': nelect, 'LDAU': 'False'} return MITRelaxSet(pmg_s, user_incar_settings=uis)
def next_struc_qe(structure, next_id, work_path, kpt_data): # ---------- copy files calc_inputs = [rin.qe_infile] for f in calc_inputs: ff = f + '_1' if f == rin.qe_infile else f if not os.path.isfile('./calc_in/' + ff): raise IOError('Could not find ./calc_in/' + ff) # ------ e.g. cp ./calc_in/xxxxx_1 work0001/xxxxx shutil.copyfile('./calc_in/' + ff, work_path + f) # ---------- append structure info. to the input file with open(work_path + rin.qe_infile, 'a') as fin: fin.write('\n') qe_structure.write(structure, work_path + rin.qe_infile, mode='a') # ---------- K_POINTS mitparamset = MITRelaxSet(structure) kpoints = mitparamset.kpoints.automatic_density_by_vol( structure, rin.kppvol[0]) with open(work_path + rin.qe_infile, 'a') as f: f.write('\n') f.write('K_POINTS automatic\n') f.write(' '.join(str(x) for x in kpoints.kpts[0]) + ' 0 0 0\n') # ---------- kpt_data kpt_data[next_id] = [] # initialize kpt_data[next_id].append(kpoints.kpts[0]) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) # ---------- return return kpt_data
def next_stage_qe(stage, work_path, kpt_data, current_id): # ---------- skip_flag skip_flag = False # ---------- prepare QE files qe_files = [rin.qe_infile, rin.qe_outfile] for f in qe_files: if not os.path.isfile(work_path + f): raise IOError('Not found ' + work_path + f) os.rename(work_path + f, work_path + 'prev_' + f) # ---------- next structure try: lines_cell = qe_structure.extract_cell_parameters(work_path + 'prev_' + rin.qe_outfile) if lines_cell is None: lines_cell = qe_structure.extract_cell_parameters(work_path + 'prev_' + rin.qe_infile) lines_atom = qe_structure.extract_atomic_positions(work_path + 'prev_' + rin.qe_outfile) if lines_atom is None: lines_atom = qe_structure.extract_atomic_positions(work_path + 'prev_' + rin.qe_infile) structure = qe_structure.from_lines(lines_cell, lines_atom) except ValueError: skip_flag = True kpt_data[current_id].append(['skip']) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) print(' error in QE, skip this structure') return skip_flag, kpt_data # ---------- copy the input file from ./calc_in finput = './calc_in/' + rin.qe_infile + '_{}'.format(stage) shutil.copyfile(finput, work_path + rin.qe_infile) # ---------- append structure info. with open(work_path + rin.qe_infile, 'a') as fin: fin.write('\n') qe_structure.write(structure, work_path + rin.qe_infile, mode='a') # ---------- K_POINTS mitparamset = MITRelaxSet(structure) kpoints = mitparamset.kpoints.automatic_density_by_vol( structure, rin.kppvol[stage - 1]) with open(work_path + rin.qe_infile, 'a') as f: f.write('\n') f.write('K_POINTS automatic\n') f.write(' '.join(str(x) for x in kpoints.kpts[0]) + ' 0 0 0\n') # ---------- kpt_data kpt_data[current_id].append(kpoints.kpts[0]) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) # ---------- return return skip_flag, kpt_data
def setup_vasp(pmg_s, time_dict, temp_dict, n_e): """ :param pmg_s: Pymatgen Structure object :param time_dict: {'timestep': timestep in fs, 'length': total length (fs)} :param temp_dict: {'initial': starting temp (K), 'final': final temp (K)} :param n_e: Number of electrons to add :return: A VaspSet """ nelect = MITRelaxSet(pmg_s).nelect if n_e > 0: print("###################################") print("# BE CAREFUL, YOU ADDED ELECTRONS #") print("###################################") nelect += n_e if time_dict['timestep'] < 2: print("dt < 2 fs! Are you sure you wanted a short MD timestep?") uis = {'NELECT': nelect} # Need to change default NBLOCK and SMASS behavior if we need temp. scaling if temp_dict['initial'] != temp_dict['final']: uis['SMASS'] = -1 uis['NBLOCK'] = 50 return MITMDSet(pmg_s, temp_dict['initial'], temp_dict['final'], time_dict['length'], time_dict['timestep'], user_incar_settings=uis)
def testVaspio_set(self): """ MIT Set から作成 """ #SOURCE_DIR = vasp_input_set src = os.path.join(self.path, 'src_poscar') dst = os.path.join(self.path, 'vaspio_set') poscar = vasp.Poscar.from_file(src, check_for_POTCAR=False) #MITRelaxSet().write_input(poscar.structure, dst) print(dir(MITRelaxSet(poscar.structure))) #print(MITRelaxSet().potcar_settings) m = MITRelaxSet(poscar.structure) m.user_incar_settings['NSW'] = 10 m.user_incar_settings['NELM'] = 60 print(m.user_incar_settings) m.write_input(dst)
def make_MITRelaxSet_vasp_inputfiles(self, structure, targetdir, write_all=True): """make VASP input files Parameters ---------- structure: Structure material structure targetdir: string target dirctory write_all: bool = True flag to use pymatgen.MITRelaxSet.write_input() or not It must be True for real run. Returns ------- boolean: always True """ outputdir = targetdir mitset = MITRelaxSet(structure, standardize=True) if write_all: mitset.write_input(outputdir) else: kpoint = mitset.kpoints incar = mitset.incar poscar = mitset.poscar poscarfile = os.path.join(outputdir, "POSCAR") poscar.write_file(poscarfile) kpointfile = os.path.join(outputdir, "KPOINT") kpoint.write_file(kpointfile) incarfile = os.path.join(outputdir, "INCAR") incar.write_file(incarfile) # skip writing "POTCAR" for debug return True
def kpt_check(struc, kppvol): mitparamset = MITRelaxSet(struc) kpoints = mitparamset.kpoints.automatic_density_by_vol(struc, kppvol) print('a =', struc.lattice.a) print('b =', struc.lattice.b) print('c =', struc.lattice.c) print(' Lattice vector') print(struc.lattice) print() print('kppvol: ', kppvol) print('k-points: ', kpoints.kpts[0])
def __init__(self, spec, label, user_incar_settings=None, user_kpoints_settings=None, additional_cust_args=None, **kwargs): """ Args: spec (dict): Specification of the job to run. label (str): "parent", "ep0" or "ep1" vasp_input_set (VaspInputSet): Input set to use. user_kpoints_settings (dict): Additional KPOINTS settings. additional_cust_args (dict): Other kwargs that are passed to RunVaspCustodian. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ # Get structure from spec assert label in ["parent", "ep0", "ep1"] structure_dict = spec[label] structure = Structure.from_dict(structure_dict) user_incar_settings = user_incar_settings or {} user_kpoints_settings = user_kpoints_settings or {} additional_cust_args = additional_cust_args or {} # Task 1: Write input sets if label == 'parent': vasp_input_set = MITRelaxSet(structure, user_incar_settings=user_incar_settings, user_kpoints_settings=user_kpoints_settings) else: # label == "ep0" or "ep1" from pymatgen_diffusion.neb.io import MVLCINEBEndPointSet vasp_input_set = MVLCINEBEndPointSet(structure, user_incar_settings=user_incar_settings, user_kpoints_settings=user_kpoints_settings) write_ep_task = WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set) # Task 2: Run VASP using Custodian cust_args = {"job_type": "normal", "gzip_output": False, "handler_group": "no_handler"} cust_args.update(additional_cust_args) run_vasp = RunVaspCustodian(vasp_cmd=">>vasp_cmd<<", gamma_vasp_cmd=">>gamma_vasp_cmd<<", **cust_args) # Task 3, 4: Transfer and PassCalLocs tasks = [write_ep_task, run_vasp, TransferNEBTask(label=label), PassCalcLocs(name=label)] super(NEBRelaxationFW, self).__init__(tasks, spec=spec, name=label, **kwargs)
def next_stage_vasp(stage, work_path, kpt_data, current_id): # ---------- skip_flag skip_flag = False # ---------- rename VASP files at the current stage vasp_files = [ 'POSCAR', 'KPOINTS', 'CONTCAR', 'OUTCAR', 'OSZICAR', 'vasprun.xml' ] for f in vasp_files: if not os.path.isfile(work_path + f): raise IOError('Not found ' + work_path + f) os.rename(work_path + f, work_path + 'stage{}_'.format(stage) + f) # ---------- cp CONTCAR POSCAR shutil.copyfile(work_path + 'stage{}_CONTCAR'.format(stage), work_path + 'POSCAR') # ---------- remove STOPCAR if os.path.isfile(work_path + 'STOPCAR'): os.remove(work_path + 'STOPCAR') # ---------- KPOINTS for the next stage using pymatgen try: structure = Structure.from_file(work_path + 'POSCAR') except ValueError: skip_flag = True kpt_data[current_id].append(['skip']) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) print(' error in VASP, skip this structure') return skip_flag, kpt_data mitparamset = MITRelaxSet(structure) # kppvol[0]: <--> stage 1, kppvol[1] <--> stage2, ... # so (stage - 1): current stage, stage: next stage in kppvol kpoints = mitparamset.kpoints.automatic_density_by_vol( structure, rin.kppvol[stage], rin.force_gamma) kpoints.write_file(work_path + 'KPOINTS') # ---------- kpt_data kpt_data[current_id].append(kpoints.kpts[0]) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) # ---------- cp INCAR_? from ./calc_in for the next stage: (stage + 1) fincar = './calc_in/INCAR_{}'.format(stage + 1) shutil.copyfile(fincar, work_path + 'INCAR') # ---------- return return skip_flag, kpt_data
def scan_U(structure, incarSetings, Umin, Umax, step): vaspInputSetList = [] for U in range(Umin, Umax + 1, step): settingCopy = dict(incarSetings) print(U) # print(settingCopy['LDAUU']) # settingCopy['LDAUU']={'Mn':0} settingCopy['LDAUU'] = {'Mn': U} settingCopy['SYSTEM'] += "U{0}".format(U) inputSet = MITRelaxSet( structure, user_kpoints_settings={'reciprocal_density': 50}, force_gamma=True, user_incar_settings=settingCopy) vaspInputSetList.append(inputSet) return vaspInputSetList
def next_struc_vasp(structure, current_id, work_path, kpt_data): # ---------- copy files calc_inputs = ['POTCAR', 'INCAR'] for f in calc_inputs: ff = f + '_1' if f == 'INCAR' else f if not os.path.isfile('./calc_in/' + ff): raise IOError('Could not find ./calc_in/' + ff) # ------ e.g. cp ./calc_in/INCAR_1 work0001/INCAR shutil.copyfile('./calc_in/' + ff, work_path + f) # ---------- generate POSCAR structure.to(fmt='poscar', filename=work_path + 'POSCAR') if not os.path.isfile(work_path + 'POSCAR'): raise IOError('Could not find {}POSCAR'.format(work_path)) # ---------- Change the title of POSCAR with open(work_path + 'POSCAR', 'r') as f: lines = f.readlines() lines[0] = 'ID_{}\n'.format(current_id) with open(work_path + 'POSCAR', 'w') as f: for line in lines: f.write(line) # ---------- generate KPOINTS using pymatgen mitparamset = MITRelaxSet(structure) kpoints = mitparamset.kpoints.automatic_density_by_vol( structure, rin.kppvol[0], rin.force_gamma) kpoints.write_file(work_path + 'KPOINTS') # ---------- kpt_data kpt_data[current_id] = [] # initialize kpt_data[current_id].append(kpoints.kpts[0]) pkl_data.save_kpt(kpt_data) out_kpts(kpt_data) # ---------- return return kpt_data
def get_endpoints_structure(self, path, layer=5, surface='1 1 1', burger_vector='0 0 0', crystal_lattice='FCC'): """ Based on the parameters introduced, constructing a slab structure oriented on the surface. Args: layer: the layer of slab. surface: the slip plane. burger_vector: the burger vector of slip system, is the multiple of a constant and a slip direction which is in miller index Returns: a list contains: Structure: includs the input parameters for function get_wf_neb_from_endpoints(), parent_slab and slip_slab, and delta_coords is the input parameter I add for get_wf_neb_from_endpoints to reserve the slip direction from parent_slab to slip_slab. POSCAR_path: the path of the new POSCAR file """ # step1 get the initial structure from POSCAR file title = "files4layer%d_%s_%s" % (layer, surface, burger_vector) new_path = os.path.join(path, title) if not os.path.isdir(new_path): os.mkdir(new_path) struc = self.init_struc Poscar(struc).write_file(new_path + '/initial_POSCAR') if (crystal_lattice == 'HCP'): logging.info("This is a HCP Structure") h, k, l = surface.split(' ') surface = (int(h), int(k), int(l)) hcp_surface_dict = { (0, 0, 1): (0, 0, 0, 1), (1, 0, 0): (1, 0, -1, 0), (1, 0, 1): (1, 0, -1, 1), (2, -1, 2): (2, -1, -1, 2) } four_coords_surface = hcp_surface_dict[surface] interplanar_spacing = self.get_interplanar_spacing( struc, four_coords_surface) else: h, k, l = surface.split(' ') surface = (int(h), int(k), int(l)) interplanar_spacing = self.get_interplanar_spacing(struc, surface) slab_size = np.ceil(interplanar_spacing * (layer - 1)) lattice = struc.lattice.matrix slabs = generate_all_slabs(struc, max_index=3, min_slab_size=slab_size, min_vacuum_size=15.0, center_slab=True) parent_slab = [slab for slab in slabs if slab.miller_index == surface][0] if self.make_supercell is True: parent_slab.make_supercell(self.supercell_matrix) ps_lattice_matrix = parent_slab.lattice.matrix cuc_lattice_matrix = np.matrix(struc.lattice.matrix) ab_across = np.cross(ps_lattice_matrix[0], ps_lattice_matrix[1]) area = np.linalg.norm(ab_across) logging.info("slip area: {}".format(area)) transform_factor = ps_lattice_matrix * cuc_lattice_matrix.I dburger_vector = np.matrix(burger_vector) * transform_factor.I dburger_vector = np.ma.round(dburger_vector, decimals=6) order = zip(range(len(parent_slab.frac_coords)), parent_slab.frac_coords, parent_slab.species) c_order = sorted(order, key=lambda x: x[1][2]) coord_seq = [] for j in c_order: coord_seq.append(j[1]) new_lattice = parent_slab.lattice new_species = parent_slab.species parent_slab = Structure(lattice=new_lattice, coords=coord_seq, species=new_species) atom_number = len(parent_slab.frac_coords) # To judge whether to dope if self.isdope is True: logging.info("We are substitute the %s by %s" % (self.formula, self.dopant)) if isinstance(self.dopant, dict): ism = self.dopant else: dope_num = atom_number / 2 ism = {dope_num: self.dopant} Dope = rsst(ism) parent_slab = Dope.apply_transformation(parent_slab) Poscar(parent_slab).write_file(new_path + '/parent_slab_POSCAR') a = float(dburger_vector[0][0]) b = float(dburger_vector[0][1]) c = float(dburger_vector[0][2]) coord_seq_1 = [] d_order = copy.deepcopy(c_order) critical_atom = int(atom_number / 2) logging.info("critical_atom: {}".format(critical_atom)) for i in d_order[0:critical_atom]: i[1][0] -= a / 2 i[1][1] -= b / 2 i[1][2] -= c / 2 coord_seq_1.append(i[1]) logging.info("d_order: {} \n".format(d_order)) logging.info("c_order after: {} \n".format(c_order)) logging.info("parent_slab_1: {} \n".format(parent_slab)) for i in d_order[critical_atom:int(atom_number)]: i[1][0] += a / 2 i[1][1] += b / 2 i[1][2] += c / 2 coord_seq_1.append(i[1]) new_lattice = parent_slab.lattice new_species = parent_slab.species frac_coords = coord_seq_1 slip_slab = Structure(lattice=new_lattice, coords=frac_coords, species=new_species) Poscar(slip_slab).write_file(new_path + '/slip_slab_POSCAR') parent_set = MITRelaxSet(parent_slab) parent_struc = parent_set.poscar.structure slip_set = MITRelaxSet(slip_slab) slip_struc = slip_set.poscar.structure delta_coords = slip_struc.frac_coords - parent_struc.frac_coords return ({ "Structure": [parent_slab, slip_slab, delta_coords], "POSACR_path": new_path })
def generate_incar(struct, dirname='.', encut=1.5): """ Generate INCAR according to user's choice. Now these templates are available: a >>> Optimization calculation b >>> SCF calculation c >>> BAND structure calculation d >>> DOS calculation e >>> ELF calculation f >>> Bader charge calculation g >>> AIMD NPT calculation h >>> AIMD NVT calculation i >>> Potential calculation j >>> Partial charge calculation k >>> STM image calculation l >>> optical properties calculation m >>> Mechanical properties calculation n >>> Frequency calculation o >>> Transition state calculation p >>> Phonopy + vasp DFPT calculation q >>> Phonopy + vasp finite difference calculation """ try: pots = Potcar.from_file(os.path.join(dirname, "POTCAR")) pot_elems = [] max_encut_elems = [] for pot in pots: pot_elems.append(pot.element) max_encut_elems.append(pot.PSCTR['ENMAX']) struct_elems = [x.value for x in struct.types_of_specie] mlog.debug('Element order in POSCAR %s' % (struct_elems)) mlog.debug('Element order in POTCAR %s' % (pot_elems)) if struct_elems == pot_elems: pass else: print("The element order in POTCAR conflicts with POSCAR ") os._exit() except: warn_tip(0, '\nPOTCAR file not found\n') max_encut_elems = [500] prop_encut = max(max_encut_elems) * encut elec_relax1['ENCUT'] = prop_encut tip='\n'+\ 'for every letter you can append another letters for extra parameters\n'+\ 'The corresponding list are: \n'+\ 'a: SPIN \n'+\ 'b: SOC \n'+\ 'c: HSE \n'+\ 'd: DIPOLE correction \n'+\ 'e: Electric filed \n'+\ 'f: Add grid \n'+\ 'g: Add Pressure \n'+\ 'h: DFT-D2 \n'+\ 'i: DFT-D3 \n'+\ 'j: VDW-DF \n'+\ 'k: opt-B86 \n'+\ 'l: opt-B88 \n'+\ 'm: LDA+U \n'+\ '\nFor exmaple: aai means one optimization by condsidering SPIN and \n'+\ 'DFT-D3 correction. \n' warn_tip(1, tip) #add tips sepline(ch=' generate INCAR file ', sp='-') print("your choice?") print('''\ a >>> Optimization calculation b >>> SCF calculation c >>> BAND structure calculation d >>> DOS calculation e >>> ELF calculation f >>> Bader charge calculation g >>> AIMD NPT calculation h >>> AIMD NVT calculation i >>> Potential calculation j >>> Partial charge calculation k >>> STM image calculation l >>> optical properties calculation m >>> Mechanical properties calculation n >>> Frequency calculation o >>> Transition state calculation p >>> Phonopy + vasp DFPT calculation q >>> Phonopy + vasp finite difference calculation ''') wait_sep() in_str = wait() choice = in_str[0] in_str = ''.join(in_str.split()) # assert choice in range(1,19) ref_incar = MITRelaxSet(struct).incar #print(ref_incar) ref_incar_cite = {} spin_paras['MAGMOM'] = ref_incar['MAGMOM'] try: LDAU_paras['LDAUJ'] = ref_incar['LDAUJ'] LDAU_paras['LDAUL'] = ref_incar['LDAUL'] except: LDAU_paras['LDAUJ'] = None LDAU_paras['LDAUL'] = None elec_relax1['LREAL'] = ref_incar['LREAL'] def parse_extra_incar(in_str, modify_val=None): incar_str = '' for i in range(1, len(in_str)): if in_str[i] != ' ': incar, comment = Incar.from_dict(eval(extra_params[in_str[i]])) incar_str += incar.get_string(pretty=True, comment=comment) return incar_str incar_str = '' if choice == 'a': # Opt calculation for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'b': # SCF calculation ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True output_paras['LWAVE'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'c': # band structure calculation ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth start_paras['ICHARG'] = 11 for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'd': # DOS calculation ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth start_paras['ICHARG'] = 11 for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'e': # ELF calculatio ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True output_paras['LELF'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'f': # Bader charge calculation ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True output_paras['LAECHG'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'g': # AIMD NPT calculation basic_paras.append('md_NPT_paras') ion_relax['NSW'] = md_step ion_relax['IBRION'] = 0 ion_relax['POTIM'] = 1 ion_relax['ISYM'] = 0 for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'h': # AIMD NVT calculation basic_paras.append('md_NVT_paras') ion_relax['NSW'] = md_step ion_relax['IBRION'] = 0 ion_relax['POTIM'] = 1 ion_relax['ISYM'] = 0 ion_relax['ISIF'] = 2 for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'i': # Potential calculation ion_relax['NSW'] = 0 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True output_paras['LVTOT'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'j': # Partial charge calculation basic_paras.append('partial_paras') ion_relax['NSW'] = 0 start_paras['ISTART'] = 1 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'k': # STM image calculation basic_paras.append('stm_paras') ion_relax['NSW'] = 0 start_paras['ISTART'] = 1 elec_relax1['EDIFF'] = ediff_oth output_paras['LCHGARG'] = True for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'l': # optical properties calculation basic_paras.append('optics_paras') ion_relax['NSW'] = 0 start_paras['ISTART'] = 1 elec_relax1['EDIFF'] = ediff_oth for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'm': # Mechanical properties calculation basic_paras.append('stm_paras') ion_relax['NSW'] = 1 ion_relax['NFREE'] = 4 ion_relax['IBRION'] = 6 ion_relax['POTIM'] = 0.015 elec_relax1['EDIFF'] = ediff_oth for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'n': # Frequency calculation ion_relax['NSW'] = 1 ion_relax['NFREE'] = 4 ion_relax['IBRION'] = 5 ion_relax['POTIM'] = 0.015 elec_relax1['EDIFF'] = ediff_oth for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'o': # Transition state calculation basic_paras.append('neb_paras') ion_relax['POTIM'] = 0 ion_relax['EDIFFG'] = ediffg_neb elec_relax1['EDIFF'] = ediff_opt for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif choice == 'p': # Phonopy + vasp DFPT calculation ion_relax['IBRION'] = 8 elec_relax1['EDIFF'] = ediff_phon basic_paras.append(grid_paras) for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) elif 'q' == choice: # Phonopy + vasp finite difference calculation ion_relax['NSW'] = 0 ion_relax['IBRION'] = -1 elec_relax1['EDIFF'] = ediff_phon basic_paras.append(grid_paras) for dict_paras in basic_paras: incar, comment = Incar.from_dict(eval(dict_paras)) incar_str += incar.get_string(pretty=True, comment=comment) if len(in_str) > 1: incar_str += parse_extra_incar(in_str) else: # left empty for extend raise Exception(f"choice '{choice}' not valid!") write_file(os.path.join(dirname, "INCAR"), incar_str)
def write_vasp_inputs(Str, VASPDir, functional='PBE', num_kpoints=25, additional_vasp_settings=None, strain=((1.01, 0, 0), (0, 1.05, 0), (0, 0, 1.03))): # This is a somewhat strange input set. Essentially the matgen input set (PBE+U), but with tigher # convergence. # This is also a somewhat outdated and convoluted way to generate VASP inputs but it should work fine. # These changes to the default input set give much better results. # Do not increaes the EDIFF to make it converge faster!!! # If convergence is too slow, reduce the K-points # This is still using PBE+U with matgen U values though. Need to use MITCompatibility (after the run) # to apply oxygen corrections and such. # In other expansions that rely on SCAN or HSE, the corrections are different - no O correction for example # In additional_vasp_settings, you can add to, or modify the default VASPsettings. VASPSettings = { "ALGO": 'VeryFast', "ISYM": 0, "ISMEAR": 0, "EDIFF": 1e-6, "NELM": 400, "NSW": 1000, "EDIFFG": -0.02, 'LVTOT': False, 'LWAVE': False, 'LCHARG': False, 'NELMDL': -6, 'NELMIN': 8, 'LSCALU': False, 'NPAR': 2, 'NSIM': 2, 'POTIM': 0.25, 'LDAU': True } if additional_vasp_settings: for key in additional_vasp_settings: VASPSettings[key] = additional_vasp_settings[key] print('Changed {} setting to {}.'.format( key, additional_vasp_settings[key])) if not os.path.isdir(VASPDir): os.mkdir(VASPDir) # Joggle the lattice to help symmetry broken relaxation. You may turn it off by setting strain=None if strain: deformation = Deformation(strain) defStr = deformation.apply_to_structure(Str) #Str=Structure(StrainedLatt,Species,FracCoords,to_unit_cell=False,coords_are_cartesian=False); VIO = MITRelaxSet(defStr, potcar_functional=functional) VIO.user_incar_settings = VASPSettings VIO.incar.write_file(os.path.join(VASPDir, 'INCAR')) VIO.poscar.write_file(os.path.join(VASPDir, 'POSCAR')) Kpoints.automatic(num_kpoints).write_file(os.path.join(VASPDir, 'KPOINTS')) # Use PAW_PBE pseudopotentials, cannot use PBE_52, this does not exist on ginar! # NOTE: For the POTCARs to work, you need to set up the VASP pseudopotential directory as per the # pymatgen instructions, and set the path to them in .pmgrc.yaml located in your home folder. # The pymatgen website has instuctrions for how to do this. POTSyms = VIO.potcar_symbols for i, Sym in enumerate(POTSyms): if Sym == 'Zr': POTSyms[i] = 'Zr_sv' Potcar(POTSyms, functional=functional).write_file(os.path.join(VASPDir, 'POTCAR'))
def main(): "main function : read runs in folder & rerun them according to user input" try: main_dir = sys.argv[1] except IndexError: main_dir = os.getcwd() print("in current folder : {}".format(main_dir)) rerun_type, incar_type = prompt_rerun_type() select_converged_runs = input( "Rerun [a]ll / [n]on-converged only / [c] converged-only ? : ") # do not parse vasprun if all job selected check_vasprun = 0 if select_converged_runs in ["a"] else 0.9 try: file_system = input("[j]ob / [p]roject / [s]uper_project ? : ")[0] except Exception: file_system = "p" print("filesystem : {}".format(file_system)) # Create a list of all the valid runs in the selected folders run_list = read.collect_valid_runs(main_dir, checkDiff=False, vasprun_parsing_lvl=check_vasprun, file_system_choice=file_system) converged_jobs = [d for d in run_list if d.status == 3] unconverged_jobs = [d for d in run_list if d.status < 3] # when reruning all jobs, they are all considered as unconverged if select_converged_runs in ["a", "n"]: rerun_list = unconverged_jobs elif select_converged_runs in ["c"]: rerun_list = converged_jobs rerun_list = filtering_runs(select_converged_runs, rerun_list) print("number of valid jobs to rerun : {}".format(len(rerun_list))) if len(rerun_list) == 0: print("no valid run") return 0 print("selected runs : \n {}".format( [print(rundict.str_id) for rundict in rerun_list])) try: perturb = float( input('Perturb the initial position of atoms ? in Angstrom ')) except Exception as ex: print("No perturbation") perturb = 0 dirname = incar_type if incar_type is not None else rerun_type print("current dirname ={}".format(dirname)) if incar_type == "fukui": fukui_nelec = float( input("nb elec for the fukui (>0: added, <0 : removed) ? ")) print("fukui electrons : {}".format(fukui_nelec)) elif rerun_type == "custom": try: tmpdir = str(input("Custom directory name ? :")) if len(tmpdir) > 0: dirname = tmpdir print(dirname) except Exception: print("error, default dirname to {}".format(dirname)) if file_system in ["p", "s"]: dirname_path = platform_id.get_file_name(main_dir, dirname) elif file_system in ["j"]: dirname_path = rerun_list[0].job_folder for rundict in rerun_list: # create Job from a RunDict job = launch.Job.from_rundict(rundict) files_to_copy = [] incar = {} if rerun_type == "identical": files_to_copy += ['INCAR', 'POTCAR', 'KPOINTS', 'CONTCAR'] # quick and dirty copy print("identical set generated") if rerun_type == "relaxation": if incar_type == "poscar_only": pass elif incar_type == "rebuild_from_scratch": pass elif incar_type == "less_precise": incar.update(less_precise_incar(job.structure)) print(" less precise set generated") elif incar_type == "more_precise": incar.update(more_precise_incar(job.structure)) print("more precise set generated") elif incar_type == "ultra_precise": incar.update(ultra_precise_incar()) print("ultra precise set generated") elif rerun_type == "custom": # incar['LDAUU']={'O': 6} # incar["NCORE"] = 8 # incar["KPAR"] = 2 # incar["NUPDOWN"] = 0 # HSE06 # incar["NSW"] = 0 # incar['LHFCALC'] = "TRUE" # incar['HFSCREEN'] = 0.2 # paramagnetic incar.update({ "ISPIN": 1 }) # anti-ferro-magnetic incar.update({ "ISPIN": 1 }) # kpt = Kpoints.gamma_automatic(kpts=(1, 1, 1), shift=(0, 0, 0)) # job.user_kpoint = kpt print("yolo!!") print("MODIFIED PARAMETERS ========", incar) print("{} set generated".format(dirname)) elif rerun_type == "single_point": if incar_type == "fukui": input_set = MITRelaxSet(job.structure) incar = rundict.parameters["incar"] incar["NELECT"] = input_set.nelect + fukui_nelec incar["NSW"] = 0 print("fukui correction added :", "\nNELECT read {} ==> wrote {}".format( input_set.nelect, input_set.nelect + fukui_nelec)) elif incar_type == "parcharg": efermi = rundict.data['efermi'] print(efermi) incar["LPARD"] = "True" below_fermi = float(input("Emin (Efermi=0) ?")) above_fermi = float(input("Emax (Efermi=0) ?")) incar["EINT"] = "{} {}".format(efermi+below_fermi, efermi+above_fermi) dirname += "_{}_{}".format(below_fermi, above_fermi) files_to_copy.append("WAVECAR") elif incar_type in ["static", "DOS"]: incar.update(single_point_incar()) if incar_type == "DOS": incar['EMIN'] = -5 incar['EMAX'] = 5 incar["NEDOS"] = 2001 # folder = prev_folder + "/DOS" # os.mkdir(folder) kpt_settings = {'reciprocal_density': 1000} else: kpt_settings = {'reciprocal_density': 300} job.user_kpoint = kpt_settings elif incar_type == "non_SCF": files_to_copy += ["CHGCAR", "CHG", "linear_KPOINTS"] incar.update({"IBRION": -1, "LCHARG": False, "LORBIT": 11, "LWAVE": False, "NSW": 0, "ISYM": 0, "ICHARG": 11, "ISMEAR": 0, "SIGMA": 0.01 }) for k in ["NELMDL", "MAGMOM"]: job.user_incar.pop(k, None) # job.set_job_folder(rerun_dir) kpt = drawkpt(rundict.structure) kpt.write_file(os.path.join( job.old_folder, "linear_KPOINTS")) job.old_folder = job.job_folder if file_system == "j": job.set_job_folder(platform_id.get_file_name(dirname_path, dirname), explicit_jobpath=True) else: if file_system == "p": job.set_job_folder(dirname_path, explicit_jobpath=False) if file_system == "s": # print(rundict.stacking) job.set_job_folder(os.path.join(dirname_path, rundict.stacking), explicit_jobpath=False) if incar.get('EDIFF', None) is not None: incar['EDIFF'] = '{:0.1E}'.format(incar['EDIFF']) for k in ["MAGMOM", "EINT", "LPARD", "SIGMA"]: job.user_incar.pop(k, None) job.user_incar.update(incar) print("INCAR \n", incar) print("JOB INCAR\n", job.user_incar) job.structure.perturb(perturb) print("explicit jobpath", job.explicit_jobpath) if rerun_type == "identical": # like "mkdir -p" (create parent if necessary) os.makedirs(job.job_folder) else: job.write_data_input() for f_name in files_to_copy: try: shutil.copy2('{0.old_folder}/{1}'.format(job, f_name), '{0.job_folder}/{1}'.format(job, f_name)) except Exception as ex: print("error when copying", f_name, ex) if input("[r]emove unconverged folders ? ") == "r": for rundict in unconverged_jobs: unconv_dir = rundict.old_folder # if input("remove {0} ? Y / N ".format(unconv_dir))=="Y" : shutil.rmtree(unconv_dir) print("{} deleted ".format(unconv_dir))
def write_kpt(struc, kppvol): mitparamset = MITRelaxSet(struc) kpoints = mitparamset.kpoints.automatic_density_by_vol(struc, kppvol) kpoints.write_file('KPOINTS')