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 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_slab_fw(slab, transmuter=False, db_file=None, vasp_input_set=None, parents=None, vasp_cmd="vasp", name="", add_slab_metadata=True, user_incar_settings=None): """ Function to generate a a slab firework. Returns a TransmuterFW if bulk_structure is specified, constructing the necessary transformations from the slab and slab generator parameters, or an OptimizeFW if only a slab is specified. Args: slab (Slab or Structure): structure or slab corresponding to the slab to be calculated transmuter (bool): whether or not to use a TransmuterFW based on slab params, if this option is selected, input slab must be a Slab object (as opposed to Structure) vasp_input_set (VaspInputSet): vasp_input_set corresponding to the slab calculation parents (Fireworks or list of ints): parent FWs db_file (string): path to database file vasp_cmd (string): vasp command name (string): name of firework add_slab_metadata (bool): whether to add slab metadata to task doc Returns: Firework corresponding to slab calculation """ vasp_input_set = vasp_input_set or MPSurfaceSet( slab, user_incar_settings=user_incar_settings) # If a bulk_structure is specified, generate the set of transformations, # else just create an optimize FW with the slab if transmuter: if not isinstance(slab, Slab): raise ValueError( "transmuter mode requires slab to be a Slab object") # Get transformation from oriented bulk and slab oriented_bulk = slab.oriented_unit_cell slab_trans_params = get_slab_trans_params(slab) trans_struct = SlabTransformation(**slab_trans_params) slab_from_bulk = trans_struct.apply_transformation(oriented_bulk) # Ensures supercell construction supercell_trans = SupercellTransformation.from_scaling_factors( round(slab.lattice.a / slab_from_bulk.lattice.a), round(slab.lattice.b / slab_from_bulk.lattice.b)) # Get site properties, set velocities to zero if not set to avoid # custodian issue site_props = slab.site_properties if 'velocities' not in site_props: site_props['velocities'] = [0. for s in slab] # Get adsorbates for InsertSitesTransformation if "adsorbate" in slab.site_properties.get("surface_properties", ""): ads_sites = [ site for site in slab if site.properties["surface_properties"] == "adsorbate" ] else: ads_sites = [] transformations = [ "SlabTransformation", "SupercellTransformation", "InsertSitesTransformation", "AddSitePropertyTransformation" ] trans_params = [ slab_trans_params, { "scaling_matrix": supercell_trans.scaling_matrix }, { "species": [site.species_string for site in ads_sites], "coords": [site.frac_coords for site in ads_sites] }, { "site_properties": site_props } ] fw = TransmuterFW(name=name, structure=oriented_bulk, transformations=transformations, transformation_params=trans_params, copy_vasp_outputs=True, db_file=db_file, vasp_cmd=vasp_cmd, parents=parents, vasp_input_set=vasp_input_set) else: fw = OptimizeFW(name=name, structure=slab, vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd, db_file=db_file, parents=parents, job_type="normal") # Add slab metadata if add_slab_metadata: parent_structure_metadata = get_meta_from_structure( slab.oriented_unit_cell) fw.tasks[-1]["additional_fields"].update({ "slab": slab, "parent_structure": slab.oriented_unit_cell, "parent_structure_metadata": parent_structure_metadata }) return fw
def get_slab_fw(slab, bulk_structure=None, slab_gen_params={}, db_file=None, vasp_input_set=None, parents=None, vasp_cmd="vasp", name=""): """ Function to generate a a slab firework. Returns a TransmuterFW if bulk_structure is specified, constructing the necessary transformations from the slab and slab generator parameters, or an OptimizeFW if only a slab is specified. Args: slab (Slab or Structure): structure or slab corresponding to the slab to be calculated bulk_structure (Structure): bulk structure corresponding to slab, if provided, slab firework is constructed as a TransmuterFW using the necessary transformations to get the slab from the bulk slab_gen_params (dict): dictionary of slab generation parameters used to generate the slab, necessary to get the slab that corresponds to the bulk structure vasp_input_set (VaspInputSet): vasp_input_set corresponding to the slab calculation parents (Fireworks or list of ints): parent FWs db_file (string): path to database file vasp_cmd (string): vasp command Returns: Firework """ vasp_input_set = vasp_input_set or MVLSlabSet(slab) # If a bulk_structure is specified, generate the set of transformations, else # just create an optimize FW with the slab if bulk_structure: if not isinstance(slab, Slab): raise ValueError( "structure input to get_slab_fw requires slab to be a slab object!" ) slab_trans_params = { "miller_index": slab.miller_index, "shift": slab.shift } slab_trans_params.update(slab_gen_params) # Get supercell parameters trans_struct = SlabTransformation(**slab_trans_params) slab_from_bulk = trans_struct.apply_transformation(bulk_structure) supercell_trans = SupercellTransformation.from_scaling_factors( round(slab.lattice.a / slab_from_bulk.lattice.a), round(slab.lattice.b / slab_from_bulk.lattice.b)) # Get adsorbates for InsertSitesTransformation if "adsorbate" in slab.site_properties.get("surface_properties", [None]): ads_sites = [ site for site in slab if site.properties["surface_properties"] == "adsorbate" ] else: ads_sites = [] transformations = [ "SlabTransformation", "SupercellTransformation", "InsertSitesTransformation", "AddSitePropertyTransformation" ] trans_params = [ slab_trans_params, { "scaling_matrix": supercell_trans.scaling_matrix }, { "species": [site.species_string for site in ads_sites], "coords": [site.frac_coords for site in ads_sites] }, { "site_properties": slab.site_properties } ] return TransmuterFW(name=name, structure=bulk_structure, transformations=transformations, transformation_params=trans_params, copy_vasp_outputs=True, db_file=db_file, vasp_cmd=vasp_cmd, parents=parents, vasp_input_set=vasp_input_set) else: return OptimizeFW(name=name, structure=slab, vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd, db_file=db_file, parents=parents, job_type="normal")