wf = get_wf_neb_from_endpoints( value[0], value[0:2], user_incar_settings=[{ 'ICHARG': 2, 'EDIFF': 5E-5, 'EDIFFG': -0.01, 'IBRION': 2 }, { 'ICHARG': 2, 'EDIFF': 5E-5, 'EDIFFG': -0.01, 'IBRION': 2 }, { 'IMAGES': 5, 'EDIFF': 1E-4, 'EDIFFG': -0.03, 'IBRION': 3, 'IOPT': 2, 'ENCUT': 520, 'ISYM': 1, 'ICHAIN': 0, 'SPRING': -5, 'LCLIMB': 'TRUE', 'NSW': 200, 'PREC': 'Accurate', 'IALGO': 48, 'ALGO': 'Fast', 'LREAL': 'Auto', 'ISIF': 2, 'ISMEAR': 1, 'SIGMA': 0.1 }], user_kpoints_settings=[{ "grid_density": kpoint }, { "grid_density": kpoint }, { "grid_density": kpoint }], additional_spec={ 'wf_name': '%s_%s_%d_%d_GSFE_NEB_Calcualtion_%s' % (formula, key.replace(" ", ""), kpoint, layer, datetime.datetime.today().strftime("%Y%m%d")), 'delta_coords': value[-1] })
def wf_nudged_elastic_band(structures, parent, c=None): """ Nudged elastic band (NEB) workflow from the given structures and config dict. 'is_optimized' default False 'neb_round' default 1 Notes: Length of Structure list and "is_optimized" are used to determine the workflow: 1 structure # The parent structure & two endpoint indexes provided; need relaxation. # The parent structure & two endpoint indexes provided; no need to relax. 2 structures # Two endpoints provided; need to relax two endpoints. # Two relaxed endpoints provided; no need to relax two endpoints. >=3 structures # All images including two endpoints are provided. Args: structures ([Structure]): 1) The parent structure 2) Two endpoint structures 3) An initial NEB path that comprises both images and endpoints parent (Structure): parent structure used to get two endpoints. c (dict): workflow config dict, basic format: {"fireworks": [], "common_params": {}, "additional_ep_params": {}, "additional_neb_params": {}}. When the length of structures is 1, "site_indices" key must be included in c. Note that "fireworks" is a list corresponding to the order of execution. Returns: Workflow """ if not (isinstance(structures, list) and len(structures) > 0): raise ValueError("structures must be a list of Structure objects!") # config initialization c = c or {} # TODO: @shyuep - config dict params are typically capitalized and intended to be global # params unless namespaced. e.g. NEB.COMMON_PARAMS if it's only settings for NEB # workflows. -computron spec = c.get("common_params", {}) is_optimized = spec.get("is_optimized", False) # TODO: @shyuep: the whole point of preset workflows is that they are supposed to be simple. # e.g., give a structure or a list of structures, and forget about the rest. Here it looks like # one needs to construct some kind of complicated configuration dictionary. Pretty sure no one # apart from the people in your group have any idea how to use these functions or set up this # config dict (which should not be necessary in the first place). -computron if c.get("fireworks"): # Check config dict file fw_list = [f['fw'] for f in c.get("fireworks")] neb_round = len([f for f in fw_list if "NEBFW" in f]) if neb_round < 1: raise ValueError( "At least one NEB Fireworks (NEBFW) is needed in the config dict!" ) if len(structures) == 1: assert "site_indices" in spec, "Site indices not provided in config dict!" assert len(spec["site_indices"] ) == 2, "Only two site indices should be provided!" if is_optimized: assert len(fw_list) == neb_round + 1 else: assert len(fw_list) == neb_round + 2 elif len(structures) == 2: if is_optimized: assert len(fw_list) == neb_round else: assert len(fw_list) == neb_round + 1 else: # Default settings if config dict is not provided. neb_round = 1 # Get user_incar_settings, user_kpoints_settings & additional_cust_args user_incar_settings = [{}] * (neb_round + 2) user_kpoints_settings = [{"grid_density": 1000}] * (neb_round + 2) additional_cust_args = [{}] * (neb_round + 2) # TODO: @shyuep - I have no idea what's going on here -computron if "fireworks" in c: for i in range(1, len(c["fireworks"]) + 1): user_incar_settings[-i] = c["fireworks"][-i].get( "user_incar_settings", {}) user_kpoints_settings[-i] = c["fireworks"][-i].get( "user_kpoints_settings", {"grid_density": 1000}) additional_cust_args[-i] = c["fireworks"][-i].get( "additional_cust_args", {}) kwargs = { "user_incar_settings": user_incar_settings, "user_kpoints_settings": user_kpoints_settings, "additional_cust_args": additional_cust_args } # Assign workflow using the number of given structures if len(structures) == 1: wf = get_wf_neb_from_structure(structure=structures[0], additional_spec=spec, **kwargs) elif len(structures) == 2: wf = get_wf_neb_from_endpoints(parent=parent, endpoints=structures, additional_spec=spec, **kwargs) else: # len(structures) >= 3 wf = get_wf_neb_from_images(parent=parent, images=structures, additional_spec=spec, **kwargs) return wf