def setUpClass(cls): cls.ref_lobsterin = Lobsterin.from_file( os.path.join( module_dir, "./../../test_files", "lobster", "Lobsterinputs", "lobsterin", )) cls.ref_lobsterin2 = Lobsterin.from_file( os.path.join(module_dir, "./../../test_files", "lobster", "lobsterins", "lobsterin2")) cls.vasp_dir = os.path.join(module_dir, "./../../test_files", "lobster", "VASP_calc_for_Lobster")
def _verify_inputs(self): user_lobsterin = Lobsterin.from_file(os.path.join(os.getcwd(), "lobsterin")) # Check lobsterin if self.get("check_lobsterin", True): ref_lobsterin = Lobsterin.from_file( os.path.join(self["ref_dir"], "inputs", "lobsterin") ) params_to_check = self.get("params_to_check", []) for p in params_to_check: if user_lobsterin.get(p, None) != ref_lobsterin.get(p, None): raise ValueError("lobsterin value of {} is inconsistent!".format(p)) logger.info("RunLobsterFake: verified inputs successfully")
def test_ioset_explicit(self): for fn in ["POSCAR.gz", "POTCAR.gz", "INCAR.gz"]: shutil.copy2(os.path.join(self.vasp_dir, fn), ".") ft = WriteLobsterinputfromIO( poscar_path="POSCAR.gz", potcar_path="POTCAR.gz", incar_path="INCAR.gz", option="standard", ) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) self.assertEqual(Lobsterin.from_file("lobsterin"), self.ref_lobsterin)
def run_task(self, fw_spec): poscar_path = self.get("poscar_path", "POSCAR") incar_path = self.get("incar_path", "INCAR") potcar_path = self.get("potcar_path", "POTCAR") option = self.get("option", "standard") user_supplied_basis = self.get("user_supplied_basis", None) if user_supplied_basis is None: lobsterinput = Lobsterin.standard_calculations_from_vasp_files( poscar_path, incar_path, potcar_path, option=option) else: lobsterinput = Lobsterin.standard_calculations_from_vasp_files( poscar_path, incar_path, None, option=option, dict_for_basis=user_supplied_basis, ) additional_input = self.get("user_lobsterin_settings", None) if additional_input: for key, parameter in additional_input.items(): lobsterinput[key] = parameter lobsterinput.write_lobsterin("lobsterin")
def test_ioset_settings(self): for fn in ["POSCAR.gz", "POTCAR.gz", "INCAR.gz"]: shutil.copy2(os.path.join(self.vasp_dir, fn), ".") # user supplied lobsterin inputs ft = WriteLobsterinputfromIO( poscar_path="POSCAR.gz", potcar_path="POTCAR.gz", incar_path="INCAR.gz", option="standard", user_lobsterin_settings={"COHPEndEnergy": 10.0}, ) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) self.assertEqual(Lobsterin.from_file("lobsterin"), self.ref_lobsterin2)
def run_task(self, fw_spec): vasp_calc_dir = self.get("calc_dir", None) vasp_calc_loc = ( get_calc_loc(self["calc_loc"], fw_spec["calc_locs"]) if self.get("calc_loc") else {} ) # get the directory that contains the Lobster dir to parse current_dir = os.getcwd() # parse the Lobster directory logger.info("PARSING DIRECTORY: {}".format(current_dir)) task_doc = {} struct = Structure.from_file(self._find_gz_file("POSCAR")) Lobsterout_here = Lobsterout(self._find_gz_file("lobsterout")) task_doc["output"] = Lobsterout_here.get_doc() Lobsterin_here = Lobsterin.from_file(self._find_gz_file("lobsterin")) task_doc["input"] = Lobsterin_here try: Lobsterin_orig = Lobsterin.from_file(self._find_gz_file("lobsterin.orig")) task_doc["orig_input"] = Lobsterin_orig except ValueError: pass # save custodian details if os.path.exists("custodian.json"): task_doc["custodian"] = loadfn("custodian.json") additional_fields = self.get("additional_fields", {}) if additional_fields: task_doc.update(additional_fields) task_doc.update(get_meta_from_structure(struct)) if vasp_calc_dir != None: task_doc["vasp_dir_name"] = vasp_calc_dir else: task_doc["vasp_dir_name"] = vasp_calc_loc["path"] task_doc["dir_name"] = current_dir # Check for additional keys to set based on the fw_spec if self.get("fw_spec_field"): task_doc.update(fw_spec[self.get("fw_spec_field")]) task_doc["state"] = "successful" task_doc = jsanitize(task_doc) # get the database connection db_file = env_chk(self.get("db_file"), fw_spec) # db insertion or taskdoc dump if not db_file: with open("task_lobster.json", "w") as f: f.write(json.dumps(task_doc, default=DATETIME_HANDLER)) else: db = VaspCalcDb.from_db_file(db_file, admin=True) db.collection = db.db["lobster"] additional_outputs = self.get("additional_outputs", None) if additional_outputs: for filename in additional_outputs: fs_id = None if os.path.isfile(filename): fs_id = put_file_in_gridfs( filename, db, collection_name="lobster_files", compress=True ) elif os.path.isfile(filename + ".gz"): fs_id = put_file_in_gridfs( filename + ".gz", db, collection_name="lobster_files", compress=False, compression_type="zlib", ) if fs_id: key_name = filename.split(".")[0].lower() + "_id" task_doc[key_name] = fs_id db.insert(task_doc) return FWAction()
def get_wf_lobster_test_basis( structure: Structure, calculation_type: str = "standard", delete_all_wavecars: bool = True, c: dict = None, address_max_basis: Optional[str] = None, address_min_basis: Optional[str] = None, user_lobsterin_settings: dict = None, user_incar_settings: dict = None, user_kpoints_settings: dict = None, isym: int = 0, additional_outputs: List[str] = None, ) -> Workflow: """ creates workflow where all possible basis functions for one compound are tested at the end, the user has to decide which projection worked best (e.g., based on chargespilling) this is the recommended workflow at the moment! Args: structure (Structure): structure object that will be used during the run calculation_type (str): only "standard" is implemented so far delete_all_wavecars (bool): all wavecars wil be deleted if True c (dict): specifications for wf, e.g. VASP_CMD, LOBSTER_CMD etc. address_max_basis (str): address to yaml file including maximum basis set (otherwise predefined file) address_min_basis (str): address to yaml file including minimum basis set (otherwise predefined file) user_lobsterin_settings (dict): change lobsterin settings here user_incar_settings (dict): change incar settings with this dict user_kpoints_settings (dict): change kpoint settings with this dict isym (int): isym setting during the VASP calculation, currently lobster can only deal with isym=-1 and isym=0 additional_outputs (list): list of additional files to be stored in the results DB. They will be stored as files in gridfs. Examples are: "ICOHPLIST.lobster" or "DOSCAR.lobster". Note that the file name should be given with the full name and the correct capitalization. Returns: """ c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) lobster_cmd = c.get("LOBSTER_CMD", LOBSTER_CMD) db_file = c.get("DB_FILE", DB_FILE) fws = [] # get the relevant potcar files! inputset = LobsterSet( structure, address_basis_file=address_max_basis, user_incar_settings=user_incar_settings, user_kpoints_settings=user_kpoints_settings, isym=isym, ) # get the basis from dict_max_basis potcar_symbols = inputset.potcar_symbols # will get all possible basis functions that have to be tested if address_max_basis is None and address_min_basis is None: list_basis_dict = Lobsterin.get_all_possible_basis_functions( structure=structure, potcar_symbols=potcar_symbols) elif address_max_basis is not None and address_min_basis is None: list_basis_dict = Lobsterin.get_all_possible_basis_functions( structure=structure, potcar_symbols=potcar_symbols, address_basis_file_max=address_max_basis, ) elif address_min_basis is not None and address_max_basis is None: list_basis_dict = Lobsterin.get_all_possible_basis_functions( structure=structure, potcar_symbols=potcar_symbols, address_basis_file_min=address_min_basis, ) elif address_min_basis is not None and address_max_basis is not None: list_basis_dict = Lobsterin.get_all_possible_basis_functions( structure=structure, potcar_symbols=potcar_symbols, address_basis_file_max=address_max_basis, address_basis_file_min=address_min_basis, ) staticfw = StaticFW( structure=structure, vasp_input_set=inputset, vasp_cmd=vasp_cmd, db_file=db_file, name="static", ) fws.append(staticfw) # append all lobster calculations that need to be done fws_lobster = [] for ibasis, basis_dict in enumerate(list_basis_dict): fws_lobster.append( LobsterFW( structure=structure, parents=staticfw, calculation_type=calculation_type, delete_wavecar=delete_all_wavecars, delete_wavecar_previous_fw=False, lobster_cmd=lobster_cmd, db_file=db_file, user_supplied_basis=basis_dict, lobsterin_key_dict=user_lobsterin_settings, handler_group="default", validator_group="strict", name="lobster_calculation_{}".format(ibasis), lobstertodb_kwargs={ "basis_id": ibasis, "number_lobster_runs": len(list_basis_dict), }, additional_outputs=additional_outputs, )) fws.extend(fws_lobster) # wavecar from static run is deleted, WAVECARs without symmetry can be huge! if delete_all_wavecars: t = DeleteFilesPrevFolder(files=["WAVECAR", "WAVECAR.gz"], calc_loc="static") final_fw = Firework([t], parents=fws_lobster, name="DelteWavecar") fws.append(final_fw) workflow = Workflow(fws, name="LobsterWorkflow") return workflow