def test_modifyincar(self): # create an INCAR incar = self.ref_incar incar.write_file(os.path.join(module_dir, "INCAR")) # modify and test ft = ModifyIncar({ "incar_update": { "ISMEAR": 1000 }, "incar_multiply": { "ENCUT": 1.5 }, "incar_dictmod": { "_inc": { "ISPIN": -1 } } }) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) incar_mod = Incar.from_file("INCAR") self.assertEqual(incar_mod['ISMEAR'], 1000) self.assertEqual(incar_mod['ENCUT'], 780) self.assertEqual(incar_mod['ISPIN'], 1)
def __init__(self, structure, isif=2, scale_lattice=None, name="static", vasp_input_set=None, vasp_cmd="vasp", metadata=None, prev_calc_loc=True, Prestatic=False, modify_incar=None, db_file=None, parents=None, tag=None, override_default_vasp_params=None, store_volumetric_data=False, **kwargs): # 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 metadata = metadata or {} tag = tag or metadata.get('tag') # generate a tag with a warning if tag is None: tag = str(uuid4()) metadata['tag'] = tag if isinstance(store_volumetric_data, (list, tuple)): store_volumetric_data = store_volumetric_data elif isinstance(store_volumetric_data, bool): if store_volumetric_data: store_volumetric_data = STORE_VOLUMETRIC_DATA else: store_volumetric_data = () else: raise ValueError('The store_volumetric_data should be list or bool') override_default_vasp_params = override_default_vasp_params or {} self.override_default_vasp_params = override_default_vasp_params vasp_input_set = vasp_input_set or StaticSet(structure, isif=isif, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties # Avoids delivery (prev_calc_loc == '' (instead by True)) t = [] if type(prev_calc_loc) == str: t.append(CopyVaspOutputs(calc_dir=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties)) elif parents: if prev_calc_loc: t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties)) else: t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties)) if (scale_lattice is not None) and not Prestatic: t.append(ScaleVolumeTransformation(scale_factor=scale_lattice, structure=structure)) t.append(ModifyIncar(incar_update=">>incar_update<<")) if modify_incar != None: t.append(ModifyIncar(incar_update=modify_incar)) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<", gzip_output=False)) t.append(PassCalcLocs(name=name)) if Prestatic: t.append(Record_PreStatic_result(db_file = ">>db_file<<", metadata = metadata, structure = structure, scale_lattice = scale_lattice)) else: t.append(VaspToDb(db_file=">>db_file<<", parse_dos=True, additional_fields={"task_label": name, "metadata": metadata, "version_atomate": atomate_ver, "version_dfttk": dfttk_ver, "adopted": True, "tag": tag}, store_volumetric_data=store_volumetric_data)) run_task_ext(t,vasp_cmd,">>db_file<<",structure,tag,self.override_default_vasp_params) t.append(CheckSymmetryToDb(db_file=">>db_file<<", tag=tag, site_properties=site_properties)) super(StaticFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def __init__(self, structure, scale_lattice=None, isif=4, override_symmetry_tolerances=None, name="structure optimization", vasp_input_set=None, job_type="normal", vasp_cmd="vasp", metadata=None, override_default_vasp_params=None, db_file=None, record_path=False, prev_calc_loc=True, parents=None, db_insert=False, tag=None, run_isif2=False, pass_isif4=False, force_gamma=True, store_volumetric_data=False, modify_incar=None, modify_incar_params={}, modify_kpoints_params={}, **kwargs): metadata = metadata or {} tag = tag or metadata.get('tag') # generate a tag with a warning if tag is None: tag = str(uuid4()) metadata['tag'] = tag metadata.update({'tag': tag}) if isinstance(store_volumetric_data, (list, tuple)): store_volumetric_data = store_volumetric_data elif isinstance(store_volumetric_data, bool): if store_volumetric_data: store_volumetric_data = STORE_VOLUMETRIC_DATA else: store_volumetric_data = () else: raise ValueError('The store_volumetric_data should be list or bool') override_default_vasp_params = override_default_vasp_params or {} override_symmetry_tolerances = override_symmetry_tolerances or {} vasp_input_set = vasp_input_set or RelaxSet(structure, isif=isif, force_gamma=force_gamma, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties t = [] # Avoids delivery (prev_calc_loc == '' (instead by True)) if type(prev_calc_loc) == str: t.append(CopyVaspOutputs(calc_dir=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties)) elif parents: if prev_calc_loc: t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties)) else: #vasp_input_set = vasp_input_set or RelaxSet(structure) # ?? t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties)) if scale_lattice is not None: t.append(ScaleVolumeTransformation(scale_factor=scale_lattice, structure=structure)) t.append(ModifyIncar(incar_update=">>incar_update<<")) if modify_incar != None: t.append(ModifyIncar(incar_update=modify_incar)) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False)) t.append(PassCalcLocs(name=name)) if record_path: t.append(Record_relax_running_path(db_file = db_file, metadata = metadata, run_isif2=run_isif2, pass_isif4=pass_isif4)) if db_insert: t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name, "metadata": metadata}, store_volumetric_data=store_volumetric_data)) t.append(CheckSymmetryToDb(db_file=db_file, tag=tag, override_symmetry_tolerances=override_symmetry_tolerances, site_properties=site_properties)) super(OptimizeFW, self).__init__(t, parents=parents, name="{}-{}".format(structure.composition.reduced_formula, name), **kwargs)
def add_modify_incar(original_wf, modify_incar_params=None, fw_name_constraint=None): """ Every FireWork that runs VASP has a ModifyIncar task just beforehand. For example, allows you to modify the INCAR based on the Worker using env_chk or using hard-coded changes. Args: original_wf (Workflow) modify_incar_params (dict) - dict of parameters for ModifyIncar. fw_name_constraint (str) - Only apply changes to FWs where fw_name contains this substring. Returns: Workflow """ modify_incar_params = modify_incar_params or { "incar_update": ">>incar_update<<" } for idx_fw, idx_t in get_fws_and_tasks( original_wf, fw_name_constraint=fw_name_constraint, task_name_constraint="RunVasp"): original_wf.fws[idx_fw].tasks.insert( idx_t, ModifyIncar(**modify_incar_params)) return original_wf
def test_modify_incar(self): # create an INCAR incar = self.ref_incar incar.write_file("INCAR") # modify and test ft = ModifyIncar( {"incar_update": {"ISMEAR": 1000}, "incar_multiply": {"ENCUT": 1.5}, "incar_dictmod": {"_inc": {"ISPIN": -1}}}) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) incar_mod = Incar.from_file("INCAR") self.assertEqual(incar_mod['ISMEAR'], 1000) self.assertEqual(incar_mod['ENCUT'], 780) self.assertEqual(incar_mod['ISPIN'], 1)
def __init__(self, structure, scale_lattice=None, name="static", vasp_input_set=None, vasp_cmd="vasp", metadata=None, prev_calc_loc=True, db_file=None, parents=None, **kwargs): # 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 metadata = metadata or {} vasp_input_set = vasp_input_set or StaticSet(structure) site_properties = deepcopy(structure).site_properties t = [] if parents: if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSetPrevStructure( vasp_input_set=vasp_input_set, site_properties=site_properties)) else: t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) if scale_lattice is not None: t.append(ScaleVolumeTransformation(scale_factor=scale_lattice)) t.append(ModifyIncar(incar_update=">>incar_update<<")) t.append( RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<", gzip_output=False)) t.append(PassCalcLocs(name=name)) t.append( VaspToDb( db_file=db_file, parse_dos=True, additional_fields={ "task_label": name, "metadata": metadata }, )) super(StaticFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def run_task(self, fw_spec): prev_checkpoint_dirs = fw_spec.get( "checkpoint_dirs", []) # If this is the first spawn, have no prev dirs prev_checkpoint_dirs.append(os.getcwd( )) # add the current directory to the list of checkpoints vasp_cmd = self["vasp_cmd"] wall_time = self["wall_time"] db_file = self.get("db_file", None) spawn_count = self["spawn_count"] production = self['production'] num_checkpoints = production.get('num_checkpoints', 1) incar_update = production.get('incar_update', None) if spawn_count > num_checkpoints: logger.info( "LOGGER: Production run completed. Took {} spawns total". format(spawn_count)) return FWAction(stored_data={'production_run_completed': True}) else: name = ("ProductionRun" + str(abs(spawn_count))) logger.info("LOGGER: Starting spawn {} of production run".format( spawn_count)) t = [] t.append( CopyVaspOutputs(calc_dir=os.getcwd(), contcar_to_poscar=True)) if incar_update: t.append(ModifyIncar(incar_update=incar_update)) t.append( RunVaspCustodian(vasp_cmd=vasp_cmd, gamma_vasp_cmd=">>vasp_gam<<", handler_group="md", wall_time=wall_time)) t.append( ProductionSpawnTask(wall_time=wall_time, vasp_cmd=vasp_cmd, db_file=db_file, spawn_count=spawn_count + 1, production=production)) new_fw = Firework(t, name=name, spec={'checkpoint_dirs': prev_checkpoint_dirs}) return FWAction( stored_data={'production_run_completed': False}, update_spec={'checkpoint_dirs': prev_checkpoint_dirs}, detours=[new_fw])
def __init__(self, structure, name="structure optimization", vasp_input_set=None, job_type="normal", vasp_cmd="vasp", isif=None, metadata=None, override_default_vasp_params=None, db_file=None, force_gamma=True, parents=None, **kwargs): """ Optimize the given structure. Args: structure (Structure): Input structure. name (str): Name for the Firework. vasp_input_set (VaspInputSet): input set to use. Defaults to MPRelaxSet() if None. override_default_vasp_params (dict): If this is not None, these params are passed to the default vasp_input_set, i.e., MPRelaxSet. This allows one to easily override some settings, e.g., user_incar_settings, etc. isif : int Shortcut to override the ISIF parameter. Defaults to None. Will take precedent over override_default_vasp_params vasp_cmd (str): Command to run vasp. db_file (str): Path to file specifying db credentials to place output parsing. force_gamma (bool): Force gamma centered kpoint generation parents ([Firework]): Parents of this particular Firework. \*\*kwargs: Other kwargs that are passed to Firework.__init__. """ metadata = metadata or {} override_default_vasp_params = override_default_vasp_params or {} vasp_input_set = vasp_input_set or PRLRelaxSet( structure, force_gamma=force_gamma, **override_default_vasp_params) t = [] t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) if isif: t.append(ModifyIncar(incar_update={'ISIF': isif})) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type)) t.append(PassCalcLocs(name=name)) t.append( VaspToDb(db_file=db_file, additional_fields={ "task_label": name, "metadata": metadata })) super(OptimizeFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def test_modify_incar(self): # create an INCAR incar = self.ref_incar incar.write_file("INCAR") # modify and test ft = ModifyIncar( incar_update={"ISMEAR": 1000}, incar_multiply={"ENCUT": 1.5}, incar_dictmod={"_inc": { "ISPIN": -1 }}, ) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) incar_mod = Incar.from_file("INCAR") self.assertEqual(incar_mod["ISMEAR"], 1000) self.assertEqual(incar_mod["ENCUT"], 780) self.assertEqual(incar_mod["ISPIN"], 1)
def __init__(self, structure, isif=7, name="structure optimization", isif4=False, level=1, override_symmetry_tolerances=None, job_type="normal", vasp_input_set=None, vasp_cmd="vasp", metadata=None, override_default_vasp_params=None, db_file=None, prev_calc_loc=True, parents=None, db_insert=False, tag=None, modify_incar_params={}, modify_kpoints_params={}, energy_with_isif={}, store_volumetric_data=False, **kwargs): metadata = metadata or {} tag = tag or metadata.get('tag') # generate a tag with a warning if tag is None: tag = str(uuid4()) metadata['tag'] = tag if isinstance(store_volumetric_data, (list, tuple)): store_volumetric_data = store_volumetric_data elif isinstance(store_volumetric_data, bool): if store_volumetric_data: store_volumetric_data = STORE_VOLUMETRIC_DATA else: store_volumetric_data = () else: raise ValueError('The store_volumetric_data should be list or bool') override_default_vasp_params = override_default_vasp_params or {} override_symmetry_tolerances = override_symmetry_tolerances or {} vasp_input_set = vasp_input_set or RelaxSet(structure, isif=isif, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties t = [] if parents: if prev_calc_loc: t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties)) else: t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties)) t.append(ModifyIncar(incar_update=">>incar_update<<")) t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False)) t.append(PassCalcLocs(name=name)) if db_insert: t.append(VaspToDb(db_file=">>db_file<<", additional_fields={"task_label": name, "metadata": metadata}, store_volumetric_data=store_volumetric_data)) t.append(CheckSymmetryToDb(db_file=">>db_file<<", tag=tag, site_properties=site_properties)) common_kwargs = {'vasp_cmd': vasp_cmd, 'db_file': ">>db_file<<", "metadata": metadata, "tag": tag, 'override_default_vasp_params': override_default_vasp_params} static_kwargs = {} relax_kwargs = {} t.append(CheckRelaxation(db_file=">>db_file<<", metadata=metadata, tag=tag, isif4=isif4, level=level, energy_with_isif=energy_with_isif, common_kwargs=common_kwargs, relax_kwargs=relax_kwargs, static_kwargs=static_kwargs, site_properties=site_properties, store_volumetric_data=store_volumetric_data, **override_symmetry_tolerances)) super().__init__(t, parents=parents, name="{}-{}".format(structure.composition.reduced_formula, name), **kwargs)
def modify_to_soc(original_wf, nbands, structure=None, modify_incar_params=None, fw_name_constraint=None): """ Takes a regular workflow and transforms its VASP fireworkers that are specified with fw_name_constraints to non-collinear calculations taking spin orbit coupling into account. Args: original_wf (Workflow) nbands (int): number of bands selected by the user (for now) structure (Structure) modify_incar_params ({}): a dictionary containing the setting for modyfining the INCAR (e.g. {"ICHARG": 11}) fw_name_constraint (string): name of the fireworks to be modified (all if None is passed) Returns: Workflow: modified with SOC """ if structure is None: try: sid = get_fws_and_tasks(original_wf, fw_name_constraint="structure optimization", task_name_constraint="WriteVasp") fw_id = sid[0][0] task_id = sid[0][1] structure = original_wf.fws[fw_id].tasks[task_id]["vasp_input_set"].structure except: raise ValueError("modify_to_soc powerup requires the structure in vasp_input_set") magmom = "" for _ in structure: magmom += "0 0 0.6 " # TODO: add saxis as an input parameter with default being (0 0 1) modify_incar_params = modify_incar_params or {"incar_update": {"LSORBIT": "T", "NBANDS": nbands, "MAGMOM": magmom, "ISPIN": 1, "LMAXMIX": 4, "ISYM": 0}} for idx_fw, idx_t in get_fws_and_tasks(original_wf, fw_name_constraint=fw_name_constraint, task_name_constraint="RunVasp"): original_wf.fws[idx_fw].tasks[idx_t]["vasp_cmd"] = ">>vasp_ncl<<" original_wf.fws[idx_fw].tasks.insert(idx_t, ModifyIncar(**modify_incar_params)) original_wf.fws[idx_fw].name += " soc" for idx_fw, idx_t in get_fws_and_tasks(original_wf, fw_name_constraint=fw_name_constraint, task_name_constraint="RunBoltztrap"): original_wf.fws[idx_fw].name += " soc" return original_wf
def __init__(self, structure, symmetry_tolerance=None, name="structure optimization", vasp_input_set=None, job_type="normal", vasp_cmd="vasp", metadata=None, override_default_vasp_params=None, db_file=None, force_gamma=True, prev_calc_loc=True, parents=None, db_insert=False, **kwargs): metadata = metadata or {} override_default_vasp_params = override_default_vasp_params or {} vasp_input_set = vasp_input_set or RelaxSet( structure, force_gamma=force_gamma, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties t = [] if parents: if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSetPrevStructure( vasp_input_set=vasp_input_set, site_properties=site_properties)) else: vasp_input_set = vasp_input_set or RelaxSet(structure) t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) t.append(ModifyIncar(incar_update=">>incar_update<<")) t.append( RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False)) t.append(PassCalcLocs(name=name)) if db_insert: t.append( VaspToDb(db_file=db_file, additional_fields={ "task_label": name, "metadata": metadata })) # This has to happen at the end because dynamically adding Fireworks if the symmetry breaks skips the rest of the tasks in the Firework. if symmetry_tolerance is not None: t.append( CheckSymmetry(tolerance=symmetry_tolerance, vasp_cmd=vasp_cmd, db_file=db_file, structure=structure, metadata=metadata, name=name)) super(OptimizeFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def __init__(self, structure, scale_lattice=None, symmetry_tolerance=None, name="structure optimization", vasp_input_set=None, job_type="normal", vasp_cmd="vasp", metadata=None, override_default_vasp_params=None, db_file=None, record_path=False, modify_incar=None, force_gamma=True, prev_calc_loc=True, parents=None, db_insert=False, Pos_Shape_relax=False, modify_incar_params={}, modify_kpoints_params={}, **kwargs): metadata = metadata or {} override_default_vasp_params = override_default_vasp_params or {} vasp_input_set = vasp_input_set or RelaxSet( structure, force_gamma=force_gamma, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties t = [] # Avoids delivery (prev_calc_loc == '' (instead by True)) if type(prev_calc_loc) == str: t.append( CopyVaspOutputs(calc_dir=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSetPrevStructure( vasp_input_set=vasp_input_set, site_properties=site_properties)) elif parents: if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSetPrevStructure( vasp_input_set=vasp_input_set, site_properties=site_properties)) else: # vasp_input_set = vasp_input_set or RelaxSet(structure) # ?? t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) if scale_lattice is not None: t.append(ScaleVolumeTransformation(scale_factor=scale_lattice)) t.append(ModifyIncar(incar_update=">>incar_update<<")) if modify_incar != None: t.append(ModifyIncar(incar_update=modify_incar)) t.append( RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False)) t.append(PassCalcLocs(name=name)) if record_path: t.append( Record_relax_running_path(db_file=db_file, metadata=metadata, Pos_Shape_relax=Pos_Shape_relax)) if db_insert: t.append( VaspToDb(db_file=db_file, additional_fields={ "task_label": name, "metadata": metadata })) # This has to happen at the end because dynamically adding Fireworks if the symmetry breaks skips the rest of the tasks in the Firework. if symmetry_tolerance is not None: t.append( CheckSymmetry(tolerance=symmetry_tolerance, vasp_cmd=vasp_cmd, db_file=db_file, structure=structure, metadata=metadata, name=name, modify_incar_params=modify_incar_params, modify_kpoints_params=modify_kpoints_params, Pos_Shape_relax=Pos_Shape_relax)) super(OptimizeFW, self).__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)
def __init__( self, structure=None, name="SCAN structure optimization", vasp_input_set=None, vasp_input_set_params=None, vasp_cmd=VASP_CMD, vdw_kernel_dir=VDW_KERNEL_DIR, prev_calc_loc=None, prev_calc_dir=None, db_file=DB_FILE, vasptodb_kwargs=None, parents=None, **kwargs, ): """ Structure optimization using the SCAN metaGGA functional. If this Firework is initialized with no parents, it will perform a GGA optimization of the provided structure using the PBESol functional. This GGA-relaxed structure is intended to be passed to a second instance of this Firework for optimization with SCAN. (see workflow definition in SCAN_optimization.yaml) 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 MpScanRelaxSet() if None. vasp_input_set_params (dict): Dict of vasp_input_set kwargs. vasp_cmd (str): Command to run vasp. vdw_kernel_dir (str): Directory containing the pre-compiled VdW kernel. Supports env_chk. 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 SCAN 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) has_previous_calc = False # Raise a warning if the InputSet is not MPScanRelaxSet, because the # kspacing calculation from bandgap is only supported in MPScanRelaxSet. if vasp_input_set and not isinstance(vasp_input_set, MPScanRelaxSet): raise UserWarning("You have specified a vasp_input_set other than \ MPScanRelaxSet. Automatic adjustment of kspacing\ is not supported by this InputSet.") if prev_calc_dir: has_previous_calc = True # Copy the CHGCAR from previous calc directory (usually PBE) t.append( CopyVaspOutputs( calc_dir=prev_calc_dir, contcar_to_poscar=True, additional_files=["CHGCAR"], )) elif parents: if prev_calc_loc: has_previous_calc = True # Copy the CHGCAR from previous calc location (usually PBE) t.append( CopyVaspOutputs( calc_loc=prev_calc_loc, contcar_to_poscar=True, additional_files=["CHGCAR"], )) else: raise UserWarning( "You specified parent Firework but did not provide its location. Set " "prev_calc_dir or prev_calc_loc and try again.") elif prev_calc_loc: raise UserWarning( "You specified prev_calc_loc but did not provide a parent Firework. Set " "parents and try again.") if has_previous_calc: # Update the InputSet with the bandgap from the previous calc t.append( WriteScanRelaxFromPrev( vasp_input_set_params=vasp_input_set_params)) # Set ICHARG to 1 to utilize the pre-existing CHGCAR settings = {"_set": {"ICHARG": 1}} if vasp_input_set_params.get("vdw"): # Copy the pre-compiled VdW kernel for VASP t.append( CopyFiles(files_to_copy=["vdw_kernel.bindat"], from_dir=vdw_kernel_dir)) # Enable vdW for the SCAN step settings["_set"]["LUSE_VDW"] = True settings["_set"]["BPARAM"] = 15.7 t.append(ModifyIncar(incar_dictmod=settings)) # use the 'scan' custodian handler group handler_group = "scan" elif structure: vasp_input_set = vasp_input_set or MPScanRelaxSet( structure, **vasp_input_set_params) t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) # Update the INCAR for the PBESol GGA preconditioning step pre_opt_settings = { "_set": { "GGA": "Ps", "METAGGA": None, "EDIFFG": -0.05 } } # Disable vdW for the precondition step if vasp_input_set_params.get("vdw"): pre_opt_settings.update( {"_unset": { "LUSE_VDW": True, "BPARAM": 15.7 }}) t.append(ModifyIncar(incar_dictmod=pre_opt_settings)) # use the 'default' custodian handler group handler_group = "default" else: raise ValueError("Must specify structure or previous calculation") # Run VASP t.append( RunVaspCustodian( vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<", handler_group=handler_group, gzip_output=False, )) t.append(PassCalcLocs(name=name)) # Parse t.append(VaspToDb(db_file=db_file, **vasptodb_kwargs)) # Delete the VdW kernel t.append(DeleteFiles(files=["vdw_kernel.bindat"])) # zip the output (don't rely on custodian to do it) t.append(GzipDir()) super().__init__(t, parents=parents, name=fw_name, **kwargs)
def __init__(self, structure, isif=4, name="structure optimization", override_symmetry_tolerances=None, job_type="normal", vasp_cmd="vasp_std", metadata=None, override_default_vasp_params=None, db_file=None, prev_calc_loc=True, parents=None, db_insert=False, tag=None, **kwargs): metadata = metadata or {} metadata = metadata or {} tag = tag or metadata.get('tag') # generate a tag with a warning if tag is None: tag = str(uuid4()) metadata['tag'] = tag override_default_vasp_params = override_default_vasp_params or {} override_symmetry_tolerances = override_symmetry_tolerances or {} vasp_input_set = RelaxSet(structure, isif=isif, **override_default_vasp_params) site_properties = deepcopy(structure).site_properties t = [] if parents: if prev_calc_loc: t.append( CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True)) t.append( WriteVaspFromIOSetPrevStructure( vasp_input_set=vasp_input_set, site_properties=site_properties)) else: t.append( WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set)) t.append(ModifyIncar(incar_update=">>incar_update<<")) t.append( RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False)) t.append(PassCalcLocs(name=name)) if db_insert: t.append( VaspToDb(db_file=db_file, additional_fields={ "task_label": name, "metadata": metadata })) common_kwargs = { 'vasp_cmd': vasp_cmd, 'db_file': db_file, "metadata": metadata, "tag": tag } relax_kwargs = {} static_kwargs = {} t.append( CheckRelaxation(db_file=db_file, metadata=metadata, tag=tag, common_kwargs=common_kwargs, relax_kwargs=relax_kwargs, static_kwargs=static_kwargs, **override_symmetry_tolerances)) super().__init__(t, parents=parents, name="{}-{}".format( structure.composition.reduced_formula, name), **kwargs)