def wf_bandstructure2D(structure, c=None): c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) vdw_kernel = c.get("VDW_KERNEL_DIR", VDW_KERNEL_DIR) incar = _read_user_incar('Relax2D.txt') print(incar) mpr2d = MPRelaxSet(structure, force_gamma=True, user_incar_settings=incar) mpr2dstatic = MPRelaxSet(structure, force_gamma=True, user_incar_settings={ "NEDOS": "3001", "EMIN": "-15.0", "EMAX": "15.0" }) #fws = [OptimizeFW2D(structure=structure, vasp_input_set=mpr2d, vasp_cmd=vasp_cmd, db_file=db_file, vdw_kernel_dir=vdw_kernel)] fws = [ OptimizeFW2D(structure=structure, vasp_input_set=mpr2d, vasp_cmd=vasp_cmd, vdw_kernel_dir=vdw_kernel) ] fws.append(StaticFW2D(parents=fws[0], vasp_input_set=mpr2dstatic)) #fws.append(NonSCFFW2D(parents=fws[1], mode='uniform')) fws.append(NonSCFFW2D(parents=fws[1], mode='line')) wf = Workflow(fws) '''check bandstructure.yaml''' ''' wf = get_wf(structure, "bandstructure.yaml", vis=MPScanRelaxSet2D(structure, force_gamma=True,), \ params=[{'vasp_input_set': mpr2d},{},{},{}], common_params={"vasp_cmd": vasp_cmd, "db_file": db_file,}) #"vdw_kernel_dir": vdw_kernel}) ''' 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("STABILITY_CHECK", STABILITY_CHECK): wf = add_stability_check(wf, fw_name_constraint="structure optimization") if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, structure) wf.name = "{}:{}".format(structure.composition.reduced_formula, "bandStructure") ''' fws = wf.fws fws[0] = new_firework print(fws) ''' return wf
def get_wf(self, num_orderings_hard_limit=16, c=None): """Retrieve Fireworks workflow. c is an optional dictionary that can contain: * heisenberg_settings: cutoff (float): Starting point for nearest neighbor search. tol (float): Tolerance for equivalent NN bonds. * mc_settings: mc_box_size (float): MC simulation box size in nm. equil_timesteps (int): Number of MC equilibration moves. mc_timesteps (int): Number of MC moves for averaging. avg (bool): Compute only <J>. * DB_FILE: path to db.json. Args: num_orderings_hard_limit (int): will make sure total number of magnetic orderings does not exceed this number even if there are extra orderings of equivalent symmetry c Optional[dict]: additional config dict described above Returns: wf (Workflow): Heisenberg Model + Vampire Monte Carlo. TODO: * Add static SCAN option (only optimization is available) """ c = c or {"DB_FILE": DB_FILE} if "DB_FILE" not in c: c["DB_FILE"] = DB_FILE heisenberg_settings = c.get("heisenberg_settings", {}) fws = [] heisenberg_model_fw = HeisenbergModelFW( wf_uuid=self.uuid, parent_structure=self.structures[0], db_file=c["DB_FILE"], heisenberg_settings=heisenberg_settings, parents=None, structures=self.structures, energies=self.energies, ) # Vampire Monte Carlo mc_settings = c.get("mc_settings", {}) vampire_fw = VampireCallerFW( wf_uuid=self.uuid, parent_structure=self.structures[0], parents=[heisenberg_model_fw], db_file=c["DB_FILE"], mc_settings=mc_settings, ) fws = [heisenberg_model_fw, vampire_fw] wf = Workflow(fws) # Add metadata wf = add_additional_fields_to_taskdocs(wf, {"wf_meta": self.wf_meta}) formula = self.structures[0].composition.reduced_formula wf.name = f"{formula} - Exchange" return wf
def wf_electron_conductivity(structure, vasp_input_set_relax=None, vasp_input_set_fixvol_relax=None, vasp_input_set_static=None, vasp_input_set_band=None, vasp_input_set_diel=None, vasp_input_set_elastic=None, vasp_kpoint_set=None, vasp_cmd=">>vasp_cmd<<", db_file=">>db_file<<", mode="standard", Temp=None, Doping=None, strain=None, ifSB=None): '''This workflow aims to calculate electronic transport properties.''' tag = datetime.utcnow().strftime('%Y-%m-%d-%H-%M-%S-%f') fws = [] # get the input set for the optimization and update it if we passed custom settings vis_relax = MPRelaxSet(structure, user_incar_settings=vasp_input_set_relax, user_kpoints_settings=vasp_kpoint_set) # Structure optimization firework fw_opt_equi = MyOptimizeFW(structure=structure, vasp_input_set=vis_relax, vasp_cmd=vasp_cmd, db_file=db_file, name="equi structure optimization", count=1, spec={"_queueadapter": { "job_name": 'opt' }}) fws.append(fw_opt_equi) #1 # static calculations firework fw_static_equi = MyStaticFW( structure=structure, vasp_input_set_params=vasp_input_set_static, prev_calc_loc="equi structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="equi static", parents=fws[0], spec={"_queueadapter": { "job_name": 'static' }}) fws.append(fw_static_equi) #2 # Structure optimization firework for 0.1% larger and 0.2% larger structures fw_opt_05 = MyOptimizeFW(structure=structure, vasp_input_set_params=vasp_input_set_fixvol_relax, strain=strain[0], prev_calc_loc="equi structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="0.5per structure optimization", count=1, parents=fws[0], spec={"_queueadapter": { "job_name": 'opt' }}) fw_opt_10 = MyOptimizeFW(structure=structure, vasp_input_set_params=vasp_input_set_fixvol_relax, strain=strain[1], prev_calc_loc="equi structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="1.0per structure optimization", count=1, parents=fws[0], spec={"_queueadapter": { "job_name": 'opt' }}) fws.append(fw_opt_05) #3 fws.append(fw_opt_10) #4 fw_static_05 = MyStaticFW( structure=structure, vasp_input_set_params=vasp_input_set_static, prev_calc_loc="0.5per structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="0.5per static", parents=fws[2], spec={"_queueadapter": { "job_name": 'static' }}) fw_static_10 = MyStaticFW( structure=structure, vasp_input_set_params=vasp_input_set_static, prev_calc_loc="1.0per structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="1.0per static", parents=fws[3], spec={"_queueadapter": { "job_name": 'static' }}) fws.append(fw_static_05) #5 fws.append(fw_static_10) #6 # band structure calculation firework fw_band_equi = MyNonSCFFW(structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="equi static", name="equi nscf", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[1], spec={"_queueadapter": { "job_name": 'band' }}) fw_band_05 = MyNonSCFFW(structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="0.5per static", name="0.5per nscf", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[4], spec={"_queueadapter": { "job_name": 'band' }}) fw_band_10 = MyNonSCFFW(structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="1.0per static", name="1.0per nscf", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[5], spec={"_queueadapter": { "job_name": 'band' }}) fws.append(fw_band_equi) #7 fws.append(fw_band_05) #8 fws.append(fw_band_10) #9 # elastic constant calculation fw_elastic = MyElasticFW(structure=structure, vasp_input_set_params=vasp_input_set_elastic, prev_calc_loc="equi structure optimization-final", name="elastic", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[1], spec={"_queueadapter": { "job_name": 'elastic' }}) fws.append(fw_elastic) #10 # dielect constant calculation fw_dielect = MyDFPTFW(structure=structure, user_incar_settings=vasp_input_set_diel, lepsilon=True, prev_calc_loc="equi static", name="dielectric", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[1], spec={"_queueadapter": { "job_name": 'dielect' }}) fws.append(fw_dielect) #11 # effective mass fw_effectivemass_CBM = MyEffectivemassFW( structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="equi static", whichbnd="CBM", stepsize=0.01, name="CBM", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[6], spec={"_queueadapter": { "job_name": 'CBM' }}) fw_effectivemass_VBM = MyEffectivemassFW( structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="equi static", whichbnd="VBM", stepsize=0.01, name="VBM", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[6], spec={"_queueadapter": { "job_name": 'VBM' }}) fw_effectivemass_CSB = MyEffectivemassFW( structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="equi static", whichbnd="CSB", stepsize=0.01, name="CSB", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[6], spec={"_queueadapter": { "job_name": 'CSB' }}) fw_effectivemass_VSB = MyEffectivemassFW( structure=structure, vasp_input_set_params=vasp_input_set_band, prev_calc_loc="equi static", whichbnd="VSB", stepsize=0.01, name="VSB", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[6], spec={"_queueadapter": { "job_name": 'VSB' }}) fws.append(fw_effectivemass_CBM) #12 fws.append(fw_effectivemass_VBM) #13 fws.append(fw_effectivemass_CSB) #14 fws.append(fw_effectivemass_VSB) #15 # Call AICON fw_eleccond = CalElecCondFW(structure=structure, name="electrical conductivity", mode=mode, Temp=Temp, Doping=Doping, ifSB=ifSB, db_file=db_file, parents=fws[6:15], spec={"_queueadapter": { "job_name": 'AICON' }}) fws.append(fw_eleccond) #16 # finally, create the workflow wf_electron_conductivity = Workflow(fws) wf_electron_conductivity.name = "{}:{}".format( structure.composition.reduced_formula, "electronic transport properties") return add_namefile(wf_electron_conductivity)
def wf_phonon_conductivity(structure, vasp_input_set_relax=None, vasp_input_set_fixvol_relax=None, vasp_input_set_dfpt=None, vasp_kpoint_set=None, vasp_cmd=">>vasp_cmd<<", db_file=">>db_file<<", Temp=None, ifscale=None, supercell=None): """ This workflow aims to calculate lattice thermal conductivity of the structure. """ fws = [] # get the input set for the optimization and update it if we passed custom settings vis_relax = MPRelaxSet(structure, user_incar_settings=vasp_input_set_relax, user_kpoints_settings=vasp_kpoint_set) # Structure optimization firework fw_opt_orig = MyOptimizeFW(structure=structure, vasp_input_set=vis_relax, vasp_cmd=vasp_cmd, db_file=db_file, name="equi structure optimization", count=1, spec={"_queueadapter": { "job_name": 'opt' }}) fws.append(fw_opt_orig) #1 # Structure optimization firework for 0.4% smaller and 0.4% larger structures fw_opt_minus = MyOptimizeFW( structure=structure, vasp_input_set_params=vasp_input_set_fixvol_relax, strain=-0.004, prev_calc_loc="equi structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="minus structure optimization", count=1, parents=fws[0], spec={"_queueadapter": { "job_name": 'opt' }}) fw_opt_plus = MyOptimizeFW( structure=structure, vasp_input_set_params=vasp_input_set_fixvol_relax, strain=0.004, prev_calc_loc="equi structure optimization-final", vasp_cmd=vasp_cmd, db_file=db_file, name="plus structure optimization", count=1, parents=fws[0], spec={"_queueadapter": { "job_name": 'opt' }}) fws.append(fw_opt_minus) #2 fws.append(fw_opt_plus) #3 # 2nd Force Constant calculation using DFPT fw_dfpt_orig = MyPhononFW( structure=structure, user_incar_settings=vasp_input_set_dfpt, prev_calc_loc="equi structure optimization-final", supercell=supercell, name="orig phonon band", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[0], spec={"_queueadapter": { "job_name": 'dfpt', "ppnode": 8 }}) fw_dfpt_minus = MyPhononFW( structure=structure, user_incar_settings=vasp_input_set_dfpt, prev_calc_loc="minus structure optimization-final", supercell=supercell, name="minus phonon band", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[1], spec={"_queueadapter": { "job_name": 'dfpt', "ppnode": 8 }}) fw_dfpt_plus = MyPhononFW( structure=structure, user_incar_settings=vasp_input_set_dfpt, prev_calc_loc="plus structure optimization-final", supercell=supercell, name="plus phonon band", vasp_cmd=vasp_cmd, db_file=db_file, parents=fws[2], spec={"_queueadapter": { "job_name": 'dfpt', "ppnode": 8 }}) fws.append(fw_dfpt_orig) #4 fws.append(fw_dfpt_minus) #5 fws.append(fw_dfpt_plus) #6 # get band.yaml and gruneisen.yaml fw_phoncond = CalPhonCondFW(structure=structure, Temp=Temp, ifscale=ifscale, supercell=supercell, name="thermal conductivity", db_file=db_file, parents=fws[3:6], spec={"_queueadapter": { "job_name": 'AICON' }}) fws.append(fw_phoncond) wf_phonon_conductivity = Workflow(fws) wf_phonon_conductivity.name = "{}:{}".format( structure.composition.reduced_formula, "phonon transport properties") return add_namefile(wf_phonon_conductivity)
def get_wf(self, c=None): """ Get the workflow. Returns: Workflow """ c = c or {"VASP_CMD": VASP_CMD, "DB_FILE": DB_FILE} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) nsites = len(self.structure.sites) vis = MPRelaxSet(self.structure, potcar_functional="PBE_54", force_gamma=True) opt_fw = OptimizeFW( self.structure, vasp_input_set=vis, vasp_cmd=c["VASP_CMD"], db_file=c["DB_FILE"], ) vis = MPStaticSet(self.structure, potcar_functional="PBE_54", force_gamma=True) static_fw = StaticFW( self.structure, vasp_input_set=vis, vasp_cmd=c["VASP_CMD"], db_file=c["DB_FILE"], parents=[opt_fw], ) # Separate FW for each BZ surface calc # Run Z2Pack on unique TRIM planes in the BZ surfaces = ["kx_0", "kx_1"] equiv_planes = self.get_equiv_planes() # Only run calcs on inequivalent BZ surfaces if self.symmetry_reduction: for add_surface in equiv_planes.keys(): mark = True for surface in surfaces: if surface in equiv_planes[add_surface]: mark = False if mark and add_surface not in surfaces: surfaces.append(add_surface) else: # 4 TRI surfaces define Z2 in 3D surfaces = ["kx_1", "ky_1", "kz_0", "kz_1"] z2pack_fws = [] for surface in surfaces: z2pack_fw = Z2PackFW( parents=[static_fw], structure=self.structure, surface=surface, uuid=self.uuid, name="z2pack", vasp_cmd=c["VASP_CMD"], db_file=c["DB_FILE"], ) z2pack_fws.append(z2pack_fw) analysis_fw = InvariantFW( parents=z2pack_fws, structure=self.structure, symmetry_reduction=self.symmetry_reduction, equiv_planes=equiv_planes, uuid=self.uuid, name="invariant", db_file=c["DB_FILE"], ) fws = [opt_fw, static_fw] + z2pack_fws + [analysis_fw] wf = Workflow(fws) wf = add_additional_fields_to_taskdocs(wf, {"wf_meta": self.wf_meta}) # Add vdW corrections if structure is layered dim_data = StructureDimensionality(self.structure) if np.any( [ dim == 2 for dim in [dim_data.larsen_dim, dim_data.cheon_dim, dim_data.gorai_dim] ] ): wf = add_modify_incar( wf, modify_incar_params={ "incar_update": { "IVDW": 11, "EDIFFG": 0.005, "IBRION": 2, "NSW": 100, } }, fw_name_constraint="structure optimization", ) wf = add_modify_incar( wf, modify_incar_params={"incar_update": {"IVDW": 11}}, fw_name_constraint="static", ) wf = add_modify_incar( wf, modify_incar_params={"incar_update": {"IVDW": 11}}, fw_name_constraint="z2pack", ) else: wf = add_modify_incar( wf, modify_incar_params={ "incar_update": {"EDIFFG": 0.005, "IBRION": 2, "NSW": 100} }, fw_name_constraint="structure optimization", ) # Helpful vasp settings and no parallelization wf = add_modify_incar( wf, modify_incar_params={ "incar_update": { "ADDGRID": ".TRUE.", "LASPH": ".TRUE.", "GGA": "PS", "NCORE": 1, } }, ) # Generate inputs for Z2Pack with a static calc wf = add_modify_incar( wf, modify_incar_params={"incar_update": {"PREC": "Accurate"}}, fw_name_constraint="static", ) wf = add_common_powerups(wf, c) wf.name = "{} {}".format(self.structure.composition.reduced_formula, "Z2Pack") if c.get("STABILITY_CHECK", STABILITY_CHECK): wf = add_stability_check(wf, fw_name_constraint="structure optimization") if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, self.structure) tag = "z2pack: {}".format(self.uuid) wf = add_tags(wf, [tag]) return wf
def get_aneb_wf( structure, working_ion, insert_coords, insert_coords_combinations, n_images, vasp_input_set=None, override_default_vasp_params=None, handler_group=None, selective_dynamics_scheme="fix_two_atom", launch_mode="all", vasp_cmd=VASP_CMD, db_file=DB_FILE, wall_time=None, additional_fields=None, tags=None, powerup_dicts=None, name="ApproxNEB", ): """ Workflow for running the "ApproxNEB" algorithm to estimate energetic barriers for a working ion in a structure (host) between end point positions specified by insert_coords and insert_coords_combinations. Note this workflow is only intended for the dilute lattice limit (where one working ion is in a large supercell structure of the host and little volume change upon insertion is expected). By default workflow sets appropriate VASP input parameters and Custodian handler groups. This workflow uses an "approx_neb" collection to organize outputs and generate inputs for new VASP calculations for easier data management and analysis. An "approx_neb" additional field is automatically added to all task docs generated to assist record keeping. To make modifications to docs generated by this workflow, use of the additional_fields and tags arguments is recommended to ensure all fireworks, tasks collection docs, and approx_neb collection docs are modified. Args: structure (Structure): structure of empty host working_ion: specie of site to insert in structure (e.g. "Li"). insert_coords (1x3 array or list of 1x3 arrays): fractional coordinates of site(s) to insert in structure (e.g. [[0,0,0], [0,0.25,0], [0.5,0,0]]). insert_coords_combinations (list of strings): list of strings corresponding to the list index of insert_coords to specify which combination of end_points to use for path interpolation. (e.g. ["0+1", "0+2"]) n_images: n_images (int): number of images interpolated between end point structures for each path set by insert_coords_combinations vasp_input_set (VaspInputSet class): can use to define VASP input parameters. See pymatgen.io.vasp.sets module for more information. MPRelaxSet() and override_default_vasp_params are used if vasp_input_set = None. override_default_vasp_params (dict): if provided, vasp_input_set is disregarded and the Vasp Input Set is created by passing override_default_vasp_params to MPRelaxSet(). Allows for easy modification of MPRelaxSet(). For example, to set ISIF=2 in the INCAR use: {"user_incar_settings":{"ISIF":2}} handler_group (str or [ErrorHandler]): group of handlers to use for RunVaspCustodian firetask. See handler_groups dict in the code for the groups and complete list of handlers in each group. Alternatively, you can specify a list of ErrorHandler objects. selective_dynamics_scheme (str): "fix_two_atom" launch_mode (str): "all" or "screening" vasp_cmd (str): the name of the full executable for running VASP. db_file (str): path to file containing the database credentials. wall_time (int): Total walltime in seconds. If this is None and the job is running on a PBS system, the handler will attempt to determine the walltime from the PBS_WALLTIME environment variable. If the wall time cannot be determined or is not set, this handler will have no effect. additional_fields (dict): specifies more information to be stored in the approx_neb collection to assist user record keeping. tags (list): list of strings to be stored in the approx_neb collection under the "tags" field to assist user record keeping. powerup_dicts (list): additional powerups given to all the dynamically created image fireworks name (str): name for the workflow returned Returns: Workflow """ approx_neb_params = override_default_vasp_params or { "user_incar_settings": { "EDIFF": 0.0005, "EDIFFG": -0.05, "IBRION": 1, "ISIF": 3, "ISMEAR": 0, "LDAU": False, "NSW": 400, "ADDGRID": True, "ISYM": 1, "NELMIN": 4, } } handler_group = handler_group or [ VaspErrorHandler(), MeshSymmetryErrorHandler(), NonConvergingErrorHandler(), PotimErrorHandler(), PositiveEnergyErrorHandler(), FrozenJobErrorHandler(), StdErrHandler(), WalltimeHandler(wall_time=wall_time), ] wf_uuid = str(uuid4()) additional_fields = deepcopy(additional_fields) host_fw = HostFW( structure=structure, approx_neb_wf_uuid=wf_uuid, db_file=db_file, vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd, override_default_vasp_params=deepcopy(approx_neb_params), additional_fields=additional_fields, tags=tags, ) # modifies incar settings needed for end point and image structure relaxations if "user_incar_settings" not in approx_neb_params.keys(): approx_neb_params = {"user_incar_settings": {}} approx_neb_params["user_incar_settings"]["ISIF"] = 2 approx_neb_params["user_incar_settings"]["ISYM"] = 0 approx_neb_params["user_incar_settings"]["LDAU"] = False end_point_fws = [] for n, coord in enumerate(insert_coords): end_point_fws.append( EndPointFW( approx_neb_wf_uuid=wf_uuid, insert_specie=working_ion, insert_coords=coord, end_points_index=n, db_file=db_file, override_default_vasp_params=approx_neb_params, parents=host_fw, )) evaluate_path_fws = [] for end_points_combo in insert_coords_combinations: if isinstance(end_points_combo, (str)): combo = end_points_combo.split("+") if len(combo) == 2: c = [int(combo[0]), int(combo[-1])] else: raise ValueError( "string format in insert_coords_combinations is incorrect") evaluate_path_fws.append( EvaluatePathFW( approx_neb_wf_uuid=wf_uuid, end_points_combo=end_points_combo, mobile_specie=working_ion, n_images=n_images, selective_dynamics_scheme=selective_dynamics_scheme, launch_mode=launch_mode, vasp_cmd=vasp_cmd, db_file=db_file, override_default_vasp_params=approx_neb_params, handler_group=handler_group, parents=[end_point_fws[c[0]], end_point_fws[c[1]]], add_additional_fields=additional_fields, add_tags=tags, )) wf = Workflow([host_fw] + end_point_fws + evaluate_path_fws) wf = use_custodian(wf, custodian_params={"handler_group": handler_group}) if isinstance(tags, (list)): wf = add_tags(wf, tags) if isinstance(additional_fields, (dict)): wf = add_additional_fields_to_taskdocs(wf, update_dict=additional_fields) if powerup_dicts is not None: wf = powerup_by_kwargs(wf, powerup_dicts) for fw in wf.fws: fw.spec["vasp_powerups"] = powerup_dicts wf.metadata.update({"approx_neb_wf_uuid": wf_uuid}) wf.name = name return wf