def main(): parser = argparse.ArgumentParser() parser.add_argument('-s', '--structure', dest='structure', help='POSCAR file of the structure.') args = parser.parse_args() struc = Structure.from_file(args.structure) # Prepare the vasp working directory working_path = os.getcwd() vasp_path = os.path.join(working_path, 'vasp_tmp') if not os.path.exists(vasp_path): os.makedirs(vasp_path) else: shutil.rmtree(vasp_path) os.makedirs(vasp_path) staticset = MPStaticSet(struc, force_gamma=True, user_incar_settings={"ICHARG": 2}) staticset.write_input(vasp_path) # chdir to vasp running directory os.chdir(vasp_path) subprocess.call("mpirun -np 10 vasp5.2-openmpi", shell=True)
def generate_old_polarization_folders(structures): """ Generate the polarization calculations (old format) from the completed scf calculation """ for name in structures: for i in range(3): # compute the Berry phase along the x-i, y- and z-directions (IGPAR = 1,2,3) # Note: calculations usualy are very sensetive to the choice of "NPPSTR" parameter. You might consider to reduce it. MPStaticSet.from_prev_calc( name, user_incar_settings={ "LBERRY": True, "IGPAR": i + 1, "ICHARG": 2, "NPAR": 2, "ALGO": "Fast", "NPPSTR": 6, "LAECHG": False, "LVHAR": False, "ISIF": 2 }, user_kpoints_settings={ "reciprocal_density": 500 }).write_input(os.path.join(name, 'Berry_' + str(i + 1))) shutil.copy(os.path.join(name, 'CHGCAR'), os.path.join(name, 'Berry_' + str(i + 1)))
def write_vasp_files_static(self): """ Writes: a folder that includes vasp input file for a single structure """ mpset = MPStaticSet(self.out_struc, reciprocal_density=1, user_incar_settings={'EDIFF': 1e-5, 'ALGO': 'F', 'ISMEAR': 0}) mpset.write_input(self.wd)
def run_task(self, fw_spec): unitcell = Structure.from_file("POSCAR") supercell = self.get("supercell", None) if supercell is not None: os.system('cp POSCAR POSCAR-unitcell') unitcell.make_supercell(supercell) lepsilon = self.get("lepsilon", False) standardize = self.get("standardize", False) other_params = self.get("other_params", {}) user_incar_settings = self.get("user_incar_settings", {}) finder = SpacegroupAnalyzer(unitcell) prims = finder.get_primitive_standard_structure() # for lepsilon runs, the kpoints should be denser if lepsilon: kpoint_set = Generate_kpoints(prims, 0.02) struct = prims elif standardize: kpoint_set = Generate_kpoints(prims, 0.03) struct = prims else: kpoint_set = Generate_kpoints(unitcell, 0.03) struct = unitcell vis = MPStaticSet(struct, user_incar_settings=user_incar_settings, user_kpoints_settings=kpoint_set, sym_prec=self.get("sym_prec", 0.1), lepsilon=lepsilon, **other_params) vis.write_input(".")
def run_task(self, fw_spec): lepsilon = self.get("lepsilon") default_reciprocal_density = 200 if lepsilon else 100 # more k-points for dielectric calc. other_params = self.get("other_params", {}) user_incar_settings = other_params.get("user_incar_settings", {}) # for lepsilon runs, set EDIFF to 1E-5 unless user says otherwise if lepsilon and "EDIFF" not in user_incar_settings and \ "EDIFF_PER_ATOM" not in user_incar_settings: if "user_incar_settings" not in other_params: other_params["user_incar_settings"] = {} other_params["user_incar_settings"]["EDIFF"] = 1E-5 vis = MPStaticSet.from_prev_calc( prev_calc_dir=self.get("prev_calc_dir", "."), reciprocal_density=self.get("reciprocal_density", default_reciprocal_density), small_gap_multiply=self.get("small_gap_multiply", None), standardize=self.get("standardize", False), sym_prec=self.get("sym_prec", 0.1), international_monoclinic=self.get("international_monoclinic", True), lepsilon=lepsilon, **other_params) vis.write_input(".")
def Static (self): from pymatgen.io.vasp.sets import MPStaticSet import shutil import os filePath=self.dire for dirpath, dirnames, filenames in os.walk(filePath): # print(dirpath) for name in dirnames: if 'static' not in str(name): path = os.path.join(filePath, name) custom_settings = {"NELM": 60,'NPAR':4} # user custom incar settings static = MPStaticSet.from_prev_calc(path, standardize=True, user_incar_settings=custom_settings) diree = os.chdir(self.dire) static.write_input("static_"+str(name)) pat = os.path.join(self.dire, "static_"+str(name)) os.chdir(pat) #定义一个更改当前目录的变量 dire2 = './vaspstd_sub' #确立脚本名称 shutil.copy(r"C:\Users\41958\.spyder-py3\vaspstd_sub", dire2 )
def __init__(self, structure=None, prev_calc_dir=None, name="static dielectric", vasp_cmd=VASP_CMD, copy_vasp_outputs=True, lepsilon=True, db_file=DB_FILE, parents=None, user_incar_settings=None, pass_nm_results=False, **kwargs): """ Static DFPT calculation Firework Args: structure (Structure): Input structure. If copy_vasp_outputs, used only to set the name of the FW. name (str): Name for the Firework. lepsilon (bool): Turn on LEPSILON to calculate polar properties vasp_cmd (str): Command to run vasp. copy_vasp_outputs (str or bool): Whether to copy outputs from previous run. Defaults to True. prev_calc_dir (str): Path to a previous calculation to copy from db_file (str): Path to file specifying db credentials. parents (Firework): Parents of this particular Firework. FW or list of FWS. user_incar_settings (dict): Parameters in INCAR to override pass_nm_results (bool): if true the normal mode eigen vals and vecs are passed so that next firework can use it. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ name = "static dielectric" if lepsilon else "phonon" fw_name = "{}-{}".format(structure.composition.reduced_formula if structure else "unknown", name) user_incar_settings = user_incar_settings or {} t = [] if prev_calc_dir: t.append(CopyVaspOutputs(calc_dir=prev_calc_dir, contcar_to_poscar=True)) t.append(WriteVaspStaticFromPrev(lepsilon=lepsilon, other_params={ 'user_incar_settings': user_incar_settings, 'force_gamma': True})) elif parents and copy_vasp_outputs: t.append(CopyVaspOutputs(calc_loc=True, contcar_to_poscar=True)) t.append(WriteVaspStaticFromPrev(lepsilon=lepsilon, other_params={ 'user_incar_settings': user_incar_settings, 'force_gamma': True})) elif structure: vasp_input_set = MPStaticSet(structure, lepsilon=lepsilon, force_gamma=True, user_incar_settings=user_incar_settings) t.append(WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) else: raise ValueError("Must specify structure or previous calculation") t.append(RunVaspCustodian(vasp_cmd=vasp_cmd)) if pass_nm_results: t.append(pass_vasp_result({"structure": "a>>final_structure", "eigenvals": "a>>normalmode_eigenvals", "eigenvecs": "a>>normalmode_eigenvecs"}, parse_eigen=True, mod_spec_key="normalmodes")) t.append(PassCalcLocs(name=name)) t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name})) super(DFPTFW, self).__init__(t, parents=parents, name=fw_name, **kwargs)
def run_task(self, fw_spec): lepsilon = self.get("lepsilon") default_reciprocal_density = 100 if not lepsilon else 200 other_params = self.get("other_params", {}) # for lepsilon runs, set EDIFF to 1E-5 unless user says otherwise user_incar_settings = self.get("other_params", {}).get("user_incar_settings", {}) if lepsilon and "EDIFF" not in user_incar_settings and "EDIFF_PER_ATOM" not in user_incar_settings: if "user_incar_settings" not in other_params: other_params["user_incar_settings"] = {} other_params["user_incar_settings"]["EDIFF"] = 1e-5 vis = MPStaticSet.from_prev_calc( prev_calc_dir=self["prev_calc_dir"], reciprocal_density=self.get("reciprocal_density", default_reciprocal_density), small_gap_multiply=self.get("small_gap_multiply", None), standardize=self.get("standardize", False), sym_prec=self.get("sym_prec", 0.1), international_monoclinic=self.get("international_monoclinic", True), lepsilon=lepsilon, **other_params ) vis.write_input(".")
def wf_bandstructure_no_opt(structure, c=None): c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) wf = get_wf( structure, "bandstructure_no_opt.yaml", vis=MPStaticSet(structure, force_gamma=True), common_params={ "vasp_cmd": vasp_cmd, "db_file": db_file }, ) wf = add_common_powerups(wf, c) if c.get("SMALLGAP_KPOINT_MULTIPLY", SMALLGAP_KPOINT_MULTIPLY): wf = add_small_gap_multiply(wf, 0.5, 5, "static") wf = add_small_gap_multiply(wf, 0.5, 5, "nscf") if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, structure) return wf
def dielectric(self,uc_type='prim',output_dir='./'): if uc_type == 'prim': uc_type = 'primitive' stru = self.stru_prim.copy() elif uc_type == 'conv': uc_type = 'conventional' stru = self.stru_conv.copy() path = os.path.join(output_dir,self.name) inputs = MPStaticSet(stru).all_input transf = {'history':[{'source':self.mpid,'unit_cell':uc_type}],'defect_type':'dielectric'} incar = inputs['INCAR'] kpoints = Kpoints.automatic_gamma_density(stru,2000) if self.is_spin_polarized: incar['ISPIN']=2 else: incar['ISPIN']=1 incar['IBRION']=8 incar['LEPSILON']=True incar['LPEAD']=True incar['EDIFF']=0.000001 incar['LWAVE']=False incar['LCHARG']=False incar['ISMEAR']=0 incar['ALGO']="Normal" incar['SIGMA']=0.01 del incar['NSW'], incar['LVHAR'], incar['LAECHG'] os.mkdir(path) f=open(path+"/transformations.json",'w') f.write(json.dumps(jsanitize(transf))) inputs['POTCAR'].write_file(path+"/POTCAR") incar.write_file(path+"/INCAR") kpoints.write_file(path+"/KPOINTS") inputs['POSCAR'].write_file(path+"/POSCAR")
def test_chgcar_db_read(self): # add the workflow structure = self.struct_si # instructs to use db_file set by FWorker, see env_chk my_wf = get_wf(structure, "static_only.yaml", vis=MPStaticSet(structure, force_gamma=True), common_params={"vasp_cmd": VASP_CMD, "db_file": ">>db_file<<"}) if not VASP_CMD: my_wf = use_fake_vasp(my_wf, ref_dirs_si) else: my_wf = use_custodian(my_wf) # set the flags for storing charge densties my_wf.fws[0].tasks[-1]["parse_chgcar"] = True my_wf.fws[0].tasks[-1]["parse_aeccar"] = True self.lp.add_wf(my_wf) # run the workflow # set the db_file variable rapidfire(self.lp, fworker=FWorker(env={"db_file": os.path.join(db_dir, "db.json")})) d = self.get_task_collection().find_one() self._check_run(d, mode="static") wf = self.lp.get_wf_by_fw_id(1) self.assertTrue(all([s == 'COMPLETED' for s in wf.fw_states.values()])) chgcar_fs_id = d["calcs_reversed"][0]["chgcar_fs_id"] accar0_fs_id = d["calcs_reversed"][0]["aeccar0_fs_id"] accar2_fs_id = d["calcs_reversed"][0]["aeccar2_fs_id"] self.assertTrue(bool(chgcar_fs_id)) self.assertTrue(bool(accar0_fs_id)) self.assertTrue(bool(accar2_fs_id))
def elastic_moduli(self,output_dir='./'): stru = self.stru_prim.copy() inputs = MPStaticSet(stru).all_input path = os.path.join(output_dir,self.name) transf = {'history':[{'source':self.mpid}],'defect_type':'elastic_moduli'} incar = inputs['INCAR'] if self.is_spin_polarized: incar['ISPIN']=2 else: incar['ISPIN']=1 incar['IBRION']=6 incar['ISIF'] = 3 incar['EDIFF'] = 1e-6 incar['ISMEAR']=0 incar['POTIM']=0.015 del incar['NSW'], incar['LVHAR'], incar['LAECHG'] os.mkdir(path) f=open(path+"/transformations.json",'w') f.write(json.dumps(jsanitize(transf))) enmax = round(max([i.PSCTR['ENMAX'] for i in inputs['POTCAR']])*1.3) incar['ENCUT'] = int(enmax) inputs['POTCAR'].write_file(path+"/POTCAR") incar.write_file(path+"/INCAR") inputs['KPOINTS'].write_file(path+"/KPOINTS") inputs['POSCAR'].write_file(path+"/POSCAR")
def get_wf_bulk_modulus(structure, deformations, vasp_input_set=None, vasp_cmd="vasp", db_file=None, user_kpoints_settings=None, eos="vinet", tag=None, user_incar_settings=None): """ Returns the workflow that computes the bulk modulus by fitting to the given equation of state. Args: structure (Structure): input structure. deformations (list): list of deformation matrices(list of lists). vasp_input_set (VaspInputSet): for the static deformation calculations vasp_cmd (str): vasp command to run. db_file (str): path to the db file. user_kpoints_settings (dict): example: {"grid_density": 7000} eos (str): equation of state used for fitting the energies and the volumes. supported equation of states: "quadratic", "murnaghan", "birch", "birch_murnaghan", "pourier_tarantola", "vinet", "deltafactor". See pymatgen.analysis.eos.py tag (str): something unique to identify the tasks in this workflow. If None a random uuid will be assigned. user_incar_settings (dict): Returns: Workflow """ tag = tag or "bulk_modulus group: >>{}<<".format(str(uuid4())) deformations = [Deformation(defo_mat) for defo_mat in deformations] vis_static = vasp_input_set or MPStaticSet( structure=structure, force_gamma=True, lepsilon=False, user_kpoints_settings=user_kpoints_settings, user_incar_settings=user_incar_settings) wf_bulk_modulus = get_wf_deformations(structure, deformations, name="bulk_modulus deformation", vasp_input_set=vis_static, vasp_cmd=vasp_cmd, db_file=db_file, tag=tag) fw_analysis = Firework(FitEOSToDb(tag=tag, db_file=db_file, eos=eos), name="fit equation of state") wf_bulk_modulus.append_wf(Workflow.from_Firework(fw_analysis), wf_bulk_modulus.leaf_fw_ids) wf_bulk_modulus.name = "{}:{}".format( structure.composition.reduced_formula, "Bulk modulus") return wf_bulk_modulus
def get_VASP_inputs(input_path, mag_prec=0.1, enum_prec=0.00001): init_structure = Structure.from_file(os.path.join(input_path, 'POSCAR')) enum_struct_list = MagneticStructureEnumerator( init_structure, transformation_kwargs={ 'symm_prec': mag_prec, 'enum_precision_parameter': enum_prec }) for i, magnetic_structure in enumerate( enum_struct_list.ordered_structures): magnetic_type = enum_struct_list.ordered_structure_origins[i] str_id = magnetic_type + str(i) vasp_out_path = os.path.join(input_path, 'vasp_inputs', str_id) relax_set = MPStaticSet(structure=magnetic_structure) relax_set.get_vasp_input().write_input(vasp_out_path) create_job_script(vasp_out_path, job_id=str_id)
def get_wf_thermal_expansion(structure, deformations, vasp_input_set=None, vasp_cmd="vasp", db_file=None, user_kpoints_settings=None, t_step=10, t_min=0, t_max=1000, mesh=(20, 20, 20), eos="vinet", pressure=0.0, copy_vasp_outputs=False, tag=None): """ Returns quasi-harmonic thermal expansion workflow. Note: phonopy package is required for the final analysis step. Args: structure (Structure): input structure. deformations (list): list of deformation matrices(list of lists). vasp_input_set (VaspInputSet) vasp_cmd (str): vasp command to run. db_file (str): path to the db file. user_kpoints_settings (dict): example: {"grid_density": 7000} t_step (float): temperature step (in K) t_min (float): min temperature (in K) t_max (float): max temperature (in K) mesh (list/tuple): reciprocal space density eos (str): equation of state used for fitting the energies and the volumes. options supported by phonopy: "vinet", "murnaghan", "birch_murnaghan". Note: pymatgen supports more options than phonopy. see pymatgen.analysis.eos.py copy_vasp_outputs (bool): whether or not copy the outputs from the previous calc (usually structure optimization) before the deformations are performed. pressure (float): in GPa tag (str): something unique to identify the tasks in this workflow. If None a random uuid will be assigned. Returns: Workflow """ try: from phonopy import Phonopy except ImportError: logger.warning("'phonopy' package NOT installed. Required for the final analysis step.") tag = tag or "thermal_expansion group: >>{}<<".format(str(uuid4())) deformations = [Deformation(defo_mat) for defo_mat in deformations] vis_static = vasp_input_set or MPStaticSet(structure, force_gamma=True, lepsilon=True, user_kpoints_settings=user_kpoints_settings) wf_alpha = get_wf_deformations(structure, deformations, name="thermal_expansion deformation", vasp_cmd=vasp_cmd, db_file=db_file, tag=tag, copy_vasp_outputs=copy_vasp_outputs, vasp_input_set=vis_static) fw_analysis = Firework(ThermalExpansionCoeffToDb(tag=tag, db_file=db_file, t_step=t_step, t_min=t_min, t_max=t_max, mesh=mesh, eos=eos, pressure=pressure), name="Thermal expansion") wf_alpha.append_wf(Workflow.from_Firework(fw_analysis), wf_alpha.leaf_fw_ids) wf_alpha.name = "{}:{}".format(structure.composition.reduced_formula, "thermal expansion") return wf_alpha
def generate_new_polarization_folders(structures): """ Generate the polarization calculations (new format) from the completed scf calculation """ for name in structures: MPStaticSet.from_prev_calc(name, user_incar_settings={ "LCALCPOL": True, "LAECHG": False, "LVHAR": False, "ISIF": 2 }, user_kpoints_settings={ "reciprocal_density": 500 }).write_input( os.path.join(name, 'Berry_new')) shutil.copy(os.path.join(name, 'CHGCAR'), os.path.join(name, 'Berry_new'))
def __init__(self, structure, name="static", vasp_input_set=None, vasp_cmd="vasp", prev_calc_loc=True, db_file=None, parents=None, **kwargs): """ Standard static calculation Firework - either from a previous location or from a structure. Args: structure (Structure): Input structure. Note that for prev_calc_loc jobs, the structure is only used to set the name of the FW and any structure with the same composition can be used. name (str): Name for the Firework. vasp_input_set (VaspInputSet): input set to use (for jobs w/no parents) Defaults to MPStaticSet() if None. vasp_cmd (str): Command to run vasp. prev_calc_loc (bool or str): If true (default), copies outputs from previous calc. If a str value, grabs a previous calculation output by name. If False/None, will create new static calculation using the provided structure. db_file (str): Path to file specifying db credentials. parents (Firework): Parents of this particular Firework. FW or list of FWS. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ # TODO: @computron - I really don't like how you need to set the structure even for # prev_calc_loc jobs. Sometimes it makes appending new FWs to an existing workflow # difficult. Maybe think about how to remove this need? -computron t = [] if parents: if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspStaticFromPrev()) else: vasp_input_set = vasp_input_set or MPStaticSet(structure) t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<")) t.append(PassCalcLocs(name=name)) t.append( VaspToDb(db_file=db_file, additional_fields={"task_label": name})) super(StaticFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def write_vasp_files_disp(self, incar_path): try: poscar_list = glob(self.wd + '/POSCAR-[0-9][0-9][0-9]') print('{} displacement poscar in total'.format(len(poscar_list))) for poscar in poscar_list: folder = 'disp-' + poscar.split('-')[-1] structure = Poscar.from_file(poscar).structure mpset = MPStaticSet( structure, user_kpoints_settings={'reciprocal_density': 250}, force_gamma=True) mpset.write_input(os.path.join(self.wd, folder)) p = subprocess.Popen(['cp', incar_path, 'INCAR'], cwd=os.path.join(self.wd, folder)) p.wait() except: print('No displacement poscars')
def get_wf_deformations( structure, deformations, name="deformation", vasp_input_set=None, vasp_cmd="vasp", db_file=None, tag="", copy_vasp_outputs=True, metadata=None, ): """ Returns a structure deformation workflow. Worfklow consists of: len(deformations) in which the structure is deformed followed by a static calculation. Args: structure (Structure): input structure to be optimized and run deformations (list of 3x3 array-likes): list of deformations name (str): some appropriate name for the transmuter fireworks. vasp_input_set (DictVaspInputSet): vasp input set for static deformed structure calculation. vasp_cmd (str): command to run db_file (str): path to file containing the database credentials. tag (str): some unique string that will be appended to the names of the fireworks so that the data from those tagged fireworks can be queried later during the analysis. copy_vasp_outputs (bool): whether or not copy the outputs from the previous calc (usually structure optimization) before the transmuter fireworks. metadata (dict): meta data Returns: Workflow """ vasp_input_set = vasp_input_set or MPStaticSet(structure, force_gamma=True) fws = [] for n, deformation in enumerate(deformations): fw = TransmuterFW( name=f"{tag} {name} {n}", structure=structure, transformations=["DeformStructureTransformation"], transformation_params=[{ "deformation": deformation.tolist() }], vasp_input_set=vasp_input_set, copy_vasp_outputs=copy_vasp_outputs, vasp_cmd=vasp_cmd, db_file=db_file, ) fws.append(fw) wfname = f"{structure.composition.reduced_formula}:{name}" return Workflow(fws, name=wfname, metadata=metadata)
def get_wf_deformations(structure, deformations, name="deformation", vasp_input_set=None, vasp_cmd="vasp", db_file=None, tag="", copy_vasp_outputs=True, metadata=None): """ Returns a structure deformation workflow. Firework 1 : structural relaxation Firework 2 - len(deformations): Deform the optimized structure and run static calculations. Args: structure (Structure): input structure to be optimized and run deformations (list of 3x3 array-likes): list of deformations name (str): some appropriate name for the transmuter fireworks. vasp_input_set (DictVaspInputSet): vasp input set for static deformed structure calculation. vasp_cmd (str): command to run db_file (str): path to file containing the database credentials. tag (str): some unique string that will be appended to the names of the fireworks so that the data from those tagged fireworks can be queried later during the analysis. copy_vasp_outputs (bool): whether or not copy the outputs from the previous calc(usually structure optimization) before the transmuter fireworks. metadata (dict): meta data Returns: Workflow """ fws, parents = [], [] vasp_input_set = vasp_input_set or MPStaticSet(structure, force_gamma=True) # Deformation fireworks with the task to extract and pass stress-strain appended to it. for n, deformation in enumerate(deformations): fw = TransmuterFW(name="{} {} {}".format(tag, name, n), structure=structure, transformations=['DeformStructureTransformation'], transformation_params=[{ "deformation": deformation.tolist() }], vasp_input_set=vasp_input_set, copy_vasp_outputs=copy_vasp_outputs, parents=parents, vasp_cmd=vasp_cmd, db_file=db_file) fws.append(fw) wfname = "{}:{}".format(structure.composition.reduced_formula, name) return Workflow(fws, name=wfname, metadata=metadata)
def write_vasp_files_dfpt(self, incar_path): """ should run only after tight, proper relaxation Write vasp files to a folder named dfpt pymatgen inputset may not work very well, so just copy incar from a source """ try: relaxed_structure = Poscar.from_file(os.path.join(self.wd, 'relax/CONTCAR')).structure supercell = self.generate_structure(relaxed_structure) mpset = MPStaticSet(supercell, user_kpoints_settings={'reciprocal_density': 250}, force_gamma=True) mpset.write_input(os.path.join(self.wd, self.dfpt_folder)) p = subprocess.Popen(['cp', incar_path, 'INCAR'], cwd=os.path.join(self.wd, self.dfpt_folder)) p.wait() except: print('make sure you have relaxed the structure in tight criteria(ediff 1e-8, ediffg 1e-3')
def Write_MPStatic_KPOINTS(structure_filename="./POSCAR", **kwargs): """ generate KPOINTS for scf cal by pymatgen.io.vasp.set.MPStaticSet. input argument: -structure_filename: a file that can be understood by pymatgen.Structure.from_file. """ struct = Structure.from_file(structure_filename) vis = MPStaticSet(structure=struct, **kwargs) folder = os.path.split(structure_filename)[0] vis.kpoints.write_file(os.path.join(folder, "KPOINTS"))
def __init__(self, structure=None, name="static", vasp_input_set=None, vasp_input_set_params=None, vasp_cmd=VASP_CMD, prev_calc_loc=True, prev_calc_dir=None, db_file=DB_FILE, vasptodb_kwargs=None, parents=None, **kwargs): """ Standard static calculation Firework - either from a previous location or from a structure. Args: structure (Structure): Input structure. Note that for prev_calc_loc jobs, the structure is only used to set the name of the FW and any structure with the same composition can be used. name (str): Name for the Firework. vasp_input_set (VaspInputSet): input set to use (for jobs w/no parents) Defaults to MPStaticSet() if None. vasp_input_set_params (dict): Dict of vasp_input_set kwargs. vasp_cmd (str): Command to run vasp. prev_calc_loc (bool or str): If true (default), copies outputs from previous calc. If a str value, retrieves a previous calculation output by name. If False/None, will create new static calculation using the provided structure. prev_calc_dir (str): Path to a previous calculation to copy from db_file (str): Path to file specifying db credentials. parents (Firework): Parents of this particular Firework. FW or list of FWS. vasptodb_kwargs (dict): kwargs to pass to VaspToDb \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ t = [] vasp_input_set_params = vasp_input_set_params or {} vasptodb_kwargs = vasptodb_kwargs or {} if "additional_fields" not in vasptodb_kwargs: vasptodb_kwargs["additional_fields"] = {} vasptodb_kwargs["additional_fields"]["task_label"] = name fw_name = "{}-{}".format(structure.composition.reduced_formula if structure else "unknown", name) if prev_calc_dir: t.append(CopyVaspOutputs(calc_dir=prev_calc_dir, contcar_to_poscar=True)) t.append(WriteVaspStaticFromPrev(other_params=vasp_input_set_params)) elif parents: if prev_calc_loc: t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspStaticFromPrev(other_params=vasp_input_set_params)) elif structure: vasp_input_set = vasp_input_set or MPStaticSet(structure, **vasp_input_set_params) t.append(WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) else: raise ValueError("Must specify structure or previous calculation") t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<")) t.append(PassCalcLocs(name=name)) t.append( VaspToDb(db_file=db_file, **vasptodb_kwargs)) super(StaticFW, self).__init__(t, parents=parents, name=fw_name, **kwargs)
def __init__(self, structure, name="static", previous_structure=False, vasp_input_set=None, vasp_cmd="vasp", db_file=None, parents=None, override_default_vasp_params=None, pass_structure=True, prev_calc_loc=False, **kwargs): """ This Firework is modified from atomate.vasp.fireworks.core.StaticFW to fit the needs of mpmorph Standard static calculation Firework - either from a previous location or from a structure. Args: structure (Structure): Input structure. Note that for prev_calc_loc jobs, the structure is only used to set the name of the FW and any structure with the same composition can be used. name (str): Name for the Firework. vasp_input_set (VaspInputSet): input set to use (for jobs w/no parents) Defaults to MPStaticSet() if None. vasp_cmd (str): Command to run vasp. prev_calc_loc (bool or str): If true (default), copies outputs from previous calc. If a str value, grabs a previous calculation output by name. If False/None, will create new static calculation using the provided structure. db_file (str): Path to file specifying db credentials. parents (Firework): Parents of this particular Firework. FW or list of FWS. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ t = [] override_default_vasp_params = override_default_vasp_params or {} vasp_input_set = vasp_input_set or MPStaticSet( structure, **override_default_vasp_params) if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) if previous_structure: t.append(PreviousStructureTask()) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<")) t.append(SaveStructureTask()) t.append(PassCalcLocs(name=name)) t.append( VaspToDb(db_file=db_file, additional_fields={"task_label": name})) name = f'{structure.composition.reduced_formula}-{name}' super(StaticFW, self).__init__(t, parents=parents, name=name, **kwargs)
def run_task(self, fw_spec): material_id = self["material_id"] dest_root = fw_spec["_fw_en"]["run_dest_root"] dest = "{}/{}/bs/{}/relax".format(dest_root, os.environ["USER"], material_id) user_incar_settings = fw_spec.get("user_incar_settings", {}) vasp_input_set = MPStaticSet.from_prev_calc( prev_calc_dir=dest, standardize=1e-3, user_incar_settings=user_incar_settings) dec = MontyDecoder() vis = dec.process_decoded(vasp_input_set.as_dict()) vis.write_input(".")
def generate_scf_folders(structures, user_incar): """ Generate calculations from the structures dictionary """ for name in structures: if os.path.exists(name) == False: os.mkdir(name) structures[name].to(fmt='POSCAR', filename='/'.join([name, 'POSCAR'])) MPStaticSet(structures[name], user_incar_settings=user_incar, user_kpoints_settings={ "reciprocal_density": 500 }).write_input(name) print(name + '\n')
def wf_static(structure, c=None): c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) wf = get_wf(structure, "static_only.yaml", vis=MPStaticSet(structure), common_params={"vasp_cmd": vasp_cmd, "db_file": db_file}) wf = add_common_powerups(wf, c) if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, structure) return wf
def run_task(self, fw_spec): self.user_incar_settings.update({"NPAR": 2}) # Get kpoint density per vol vol = Poscar.from_file("POSCAR").structure.volume kppra_vol = self.kpoints_density / vol new_set = MPStaticSet.from_prev_calc( os.getcwd(), user_incar_settings=self.user_incar_settings, reciprocal_density=kppra_vol) new_set.write_input('.') structure = new_set.structure sga = SpacegroupAnalyzer(structure, 0.1) return FWAction(stored_data={ 'refined_structure': sga.get_refined_structure().as_dict(), 'conventional_standard_structure': sga.get_conventional_standard_structure().as_dict(), 'symmetry_dataset': sga.get_symmetry_dataset(), 'symmetry_operations': [x.as_dict() for x in sga.get_symmetry_operations()]})
def wf_elastic_constant(structure, c=None, order=2, sym_reduce=False): c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) uis_optimize = {"ENCUT": 700, "EDIFF": 1e-6, "LAECHG": False} if order > 2: uis_optimize.update({"EDIFF": 1e-10, "EDIFFG": -0.001, "ADDGRID": True, "LREAL": False, "ISYM": 0}) # This ensures a consistent k-point mesh across all calculations # We also turn off symmetry to prevent VASP from changing the # mesh internally kpts_settings = Kpoints.automatic_density(structure, 40000, force_gamma=True) stencils = np.linspace(-0.075, 0.075, 7) else: kpts_settings = {'grid_density': 7000} stencils = None uis_static = uis_optimize.copy() uis_static.update({'ISIF': 2, 'IBRION': 2, 'NSW': 99, 'ISTART': 1, "PREC": "High"}) # input set for structure optimization vis_relax = MPRelaxSet(structure, force_gamma=True, user_incar_settings=uis_optimize, user_kpoints_settings=kpts_settings) # optimization only workflow wf = get_wf(structure, "optimize_only.yaml", vis=vis_relax, params=[{"vasp_cmd": vasp_cmd, "db_file": db_file, "name": "elastic structure optimization"}]) vis_static = MPStaticSet(structure, force_gamma=True, lepsilon=False, user_kpoints_settings=kpts_settings, user_incar_settings=uis_static) # deformations wflow for elasticity calculation wf_elastic = get_wf_elastic_constant(structure, vasp_cmd=vasp_cmd, db_file=db_file, order=order, stencils=stencils, copy_vasp_outputs=True, vasp_input_set=vis_static, sym_reduce=sym_reduce) wf.append_wf(wf_elastic, wf.leaf_fw_ids) wf = add_common_powerups(wf, c) if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, structure) return wf
def setUp(self): coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) lattice = [ [3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603], ] structure = Structure(lattice, ["Si", "Si"], coords) input_sets = { "GGA Structure Optimization": MPRelaxSet(structure), "GGA Static": MPStaticSet(structure), "GGA NSCF Line": MPNonSCFSet(structure, mode="line"), "GGA NSCF Uniform": MPNonSCFSet(structure, mode="uniform"), } tasks = [] t_id = 1 for task_type, input_set in input_sets.items(): doc = { "true_task_type": task_type, "last_updated": datetime.now(), "task_id": t_id, "state": "successful", "orig_inputs": { "incar": input_set.incar.as_dict(), "kpoints": input_set.kpoints.as_dict(), }, "output": { "structure": structure.as_dict() }, } t_id += 1 tasks.append(doc) self.test_tasks = MemoryStore("tasks") self.task_types = MemoryStore("task_types") self.test_tasks.connect() self.task_types.connect() self.test_tasks.update(tasks)
def __init__(self, structure, transformations, transformation_params=None, vasp_input_set=None, prev_calc_dir=None, name="structure transmuter", vasp_cmd=VASP_CMD, copy_vasp_outputs=True, db_file=DB_FILE, parents=None, override_default_vasp_params=None, **kwargs): """ Apply the transformations to the input structure, write the input set corresponding to the transformed structure, and run vasp on them. Note that if a transformation yields many structures from one, only the last structure in the list is used. Args: structure (Structure): Input structure. transformations (list): list of names of transformation classes as defined in the modules in pymatgen.transformations. eg: transformations=['DeformStructureTransformation', 'SupercellTransformation'] transformation_params (list): list of dicts where each dict specify the input parameters to instantiate the transformation class in the transformations list. vasp_input_set (VaspInputSet): VASP input set, used to write the input set for the transmuted structure. name (string): Name for the Firework. vasp_cmd (string): Command to run vasp. copy_vasp_outputs (bool): Whether to copy outputs from previous run. Defaults to True. prev_calc_dir (str): Path to a previous calculation to copy from db_file (string): Path to file specifying db credentials. parents (Firework): Parents of this particular Firework. FW or list of FWS. override_default_vasp_params (dict): additional user input settings for vasp_input_set. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ fw_name = "{}-{}".format(structure.composition.reduced_formula, name) override_default_vasp_params = override_default_vasp_params or {} t = [] vasp_input_set = vasp_input_set or MPStaticSet( structure, force_gamma=True, **override_default_vasp_params) if prev_calc_dir: t.append( CopyVaspOutputs(calc_dir=prev_calc_dir, contcar_to_poscar=True)) t.append( WriteTransmutedStructureIOSet( transformations=transformations, transformation_params=transformation_params, vasp_input_set=vasp_input_set, override_default_vasp_params=override_default_vasp_params, prev_calc_dir=".")) elif copy_vasp_outputs: t.append(CopyVaspOutputs(calc_loc=True, contcar_to_poscar=True)) t.append( WriteTransmutedStructureIOSet( structure=structure, transformations=transformations, transformation_params=transformation_params, vasp_input_set=vasp_input_set, override_default_vasp_params=override_default_vasp_params, prev_calc_dir=".")) elif structure: t.append( WriteTransmutedStructureIOSet( structure=structure, transformations=transformations, transformation_params=transformation_params, vasp_input_set=vasp_input_set, override_default_vasp_params=override_default_vasp_params)) else: raise ValueError("Must specify structure or previous calculation") t.append(RunVaspCustodian(vasp_cmd=vasp_cmd)) t.append(PassCalcLocs(name=name)) t.append( VaspToDb(db_file=db_file, additional_fields={ "task_label": name, "transmuter": { "transformations": transformations, "transformation_params": transformation_params } })) super(TransmuterFW, self).__init__(t, parents=parents, name=fw_name, **kwargs)
def get_jobs(args): # Returns a generator of jobs. Allows of "infinite" jobs. vasp_command = args.command.split() # save initial INCAR for rampU runs n_ramp_u = args.jobs.count('rampU') ramps = 0 if n_ramp_u: incar = Incar.from_file('INCAR') ldauu = incar['LDAUU'] ldauj = incar['LDAUJ'] njobs = len(args.jobs) post_settings = [] # append to this list to have settings applied on next job for i, job in enumerate(args.jobs): final = False if i != njobs - 1 else True if any(c.isdigit() for c in job): suffix = "." + job else: suffix = ".{}{}".format(job, i + 1) settings = post_settings post_settings = [] backup = True if i == 0 else False copy_magmom = False vinput = VaspInput.from_directory(".") if i > 0: settings.append( {"file": "CONTCAR", "action": {"_file_copy": {"dest": "POSCAR"}}}) job_type = job.lower() auto_npar = True if args.no_auto_npar: auto_npar = False if job_type.startswith("static_derived"): from pymatgen.io.vasp.sets import MPStaticSet vis = MPStaticSet.from_prev_calc( ".", user_incar_settings={"LWAVE": True, "EDIFF": 1e-6}, ediff_per_atom=False) settings.extend([ {"dict" : "INCAR", "action": {"_set": dict(vis.incar)}}, {'dict': 'KPOINTS', 'action': {'_set': vis.kpoints.as_dict()}}]) if job_type.startswith("static_dielectric_derived"): from pymatgen.io.vasp.sets import MPStaticSet, MPStaticDielectricDFPTVaspInputSet # vis = MPStaticSet.from_prev_calc( # ".", user_incar_settings={"EDIFF": 1e-6, "IBRION": 8, # "LEPSILON": True, 'LREAL':False, # "LPEAD": True, "ISMEAR": 0, # "SIGMA": 0.01}, # ediff_per_atom=False) vis = MPStaticDielectricDFPTVaspInputSet() incar = vis.get_incar(vinput["POSCAR"].structure) unset = {} for k in ["NPAR", "KPOINT_BSE", "LAECHG", "LCHARG", "LVHAR", "NSW"]: incar.pop(k, None) if k in vinput["INCAR"]: unset[k] = 1 kpoints = vis.get_kpoints(vinput["POSCAR"].structure) settings.extend([ {"dict": "INCAR", "action": {"_set": dict(incar), "_unset": unset}}, {'dict': 'KPOINTS', 'action': {'_set': kpoints.as_dict()}}]) auto_npar = False elif job_type.startswith("static"): m = [i * args.static_kpoint for i in vinput["KPOINTS"].kpts[0]] settings.extend([ {"dict": "INCAR", "action": {"_set": {"NSW": 0}}}, {'dict': 'KPOINTS', 'action': {'_set': {'kpoints': [m]}}}]) elif job_type.startswith("nonscf_derived"): from pymatgen.io.vasp.sets import MPNonSCFSet vis = MPNonSCFSet.from_prev_calc(".", copy_chgcar=False, user_incar_settings={"LWAVE": True}) settings.extend([ {"dict": "INCAR", "action": {"_set": dict(vis.incar)}}, {'dict': 'KPOINTS', 'action': {'_set': vis.kpoints.as_dict()}}]) elif job_type.startswith("optics_derived"): from pymatgen.io.vasp.sets import MPNonSCFSet vis = MPNonSCFSet.from_prev_calc( ".", optics=True, copy_chgcar=False, nedos=2001, mode="uniform", nbands_factor=5, user_incar_settings={"LWAVE": True, "ALGO": "Exact", "SIGMA": 0.01, "EDIFF": 1e-6}, ediff_per_atom=False) settings.extend([ {"dict": "INCAR", "action": {"_set": dict(vis.incar)}}, {'dict': 'KPOINTS', 'action': {'_set': vis.kpoints.as_dict()}}]) elif job_type.startswith("rampu"): f = ramps / (n_ramp_u - 1) settings.append( {"dict": "INCAR", "action": {"_set": {"LDAUJ": [j * f for j in ldauj], "LDAUU": [u * f for u in ldauu]}}}) copy_magmom = True ramps += 1 elif job_type.startswith("quick_relax") or job_type.startswith(\ "quickrelax"): kpoints = vinput["KPOINTS"] incar = vinput["INCAR"] structure = vinput["POSCAR"].structure if "ISMEAR" in incar: post_settings.append( {"dict": "INCAR", "action": {"_set": {"ISMEAR": incar["ISMEAR"]}}}) else: post_settings.append( {"dict": "INCAR", "action": {"_unset": {"ISMEAR": 1}}}) post_settings.append({"dict": "KPOINTS", "action": {"_set": kpoints.as_dict()}}) # lattice vectors with length < 9 will get >1 KPOINT low_kpoints = Kpoints.gamma_automatic( [max(int(18/l), 1) for l in structure.lattice.abc]) settings.extend([ {"dict": "INCAR", "action": {"_set": {"ISMEAR": 0}}}, {'dict': 'KPOINTS', 'action': {'_set': low_kpoints.as_dict()}}]) # let vasp determine encut (will be lower than # needed for compatibility with other runs) if "ENCUT" in incar: post_settings.append( {"dict": "INCAR", "action": {"_set": {"ENCUT": incar["ENCUT"]}}}) settings.append( {"dict": "INCAR", "action": {"_unset": {"ENCUT": 1}}}) elif job_type.startswith("relax"): pass elif job_type.startswith("full_relax"): for j in VaspJob.full_opt_run( vasp_command): yield j else: print("Unsupported job type: {}".format(job)) sys.exit(-1) if not job_type.startswith("full_relax"): yield VaspJob(vasp_command, final=final, suffix=suffix, backup=backup, settings_override=settings, copy_magmom=copy_magmom, auto_npar=auto_npar)